Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 02bbfbc0c4df4896f3c2a7e1a75f22c0282ccd5f (plain) (tree)






















                                                                                 
                                                            
                                                          
                                  
 
          

                               
                               









                                                      


                                                                                       



                                                                                                                  
                                                                                            












                                                                                                                           
                                                                                                                                                         
































































                                                                                                                   

                                                                                                         
                                    
                                                                      


                                             

                                                  
                                

                                                                                  






















                                                                                                                          


                                                                  

                                              



                                                                                                       


                   
/*******************************************************************************
 * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * CONTRIBUTORS:
 * 		Eyrak Pean (initial contribution)
 * 		Juergen Haug
 * 
 *******************************************************************************/

package org.eclipse.etrice.generator.gnuplot

import com.google.inject.Inject
import org.eclipse.etrice.core.common.base.Annotation
import org.eclipse.etrice.core.common.base.IntLiteral
import org.eclipse.etrice.core.common.base.KeyValue
import org.eclipse.etrice.core.common.base.RealLiteral
import org.eclipse.etrice.core.common.base.StringLiteral
import org.eclipse.etrice.core.genmodel.etricegen.Root
import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
import org.eclipse.etrice.generator.base.io.IGeneratorFileIO
import org.eclipse.etrice.generator.generic.RoomExtensions
import com.google.inject.Singleton

@Singleton
class GnuplotScriptGenerator { 
	@Inject
	IGeneratorFileIO fileIo

	@Inject
	extension RoomExtensions roomExtensions

	def doGenerate(Root root) {
		if (root.subSystemInstances.empty)
			return;

		// TODO: warning more than one ssi
		val ssi = root.subSystemInstances.head
		if(!ssi.subSystemClass.annotations.exists[a |a.type.name == "Gnuplot"])
			return;
		
		val path = ssi.subSystemClass.getGenerationTargetPath
		val infoPath = ssi.subSystemClass.generationInfoPath
		try {
			fileIo.generateFile("Generating gnuplot script for subsystem " + ssi.name, path, infoPath,
				"/gnuplot/main.data.csv-script.plt", ssi.generatePlotScript)
			fileIo.generateFile("Generating gnuplot launch configuration", path, infoPath,
				"/gnuplot/create_gnuplot.launch", gnuPlotLaunchFile)
		} catch (Exception e) {
			//e.printStackTrace
		}

	}

	def protected gnuPlotLaunchFile() '''
		<?xml version="1.0" encoding="UTF-8" standalone="no"?>
		<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
		<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/>
		<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${system_path:gnuplot}"/>
		<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="${project_loc}/src-gen/gnuplot/main.data.csv-script.plt"/>
		<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${project_loc}"/>
		</launchConfiguration>

	'''

	def protected getAttribute(Annotation anno, String name) {
		anno.attributes.findFirst[attr|attr.key == name]
	}

	def protected asString(KeyValue kv) {
		if (kv.value instanceof StringLiteral)
			(kv.value as StringLiteral).value
		else
			null
	}

	def protected asReal(KeyValue kv) {
		if (kv.value instanceof RealLiteral)
			(kv.value as RealLiteral).value
		else if (kv.value instanceof IntLiteral)
			(kv.value as IntLiteral).value as double
		else
			null
	}

	def protected asInteger(KeyValue kv) {
		if (kv.value instanceof IntLiteral)
			(kv.value as IntLiteral).value
		else
			null
	}

	def protected generatePlotScript(SubSystemInstance ssi) {

		// TODO: warn if more than one GnuPlot annotation
		val plotAnnotation = ssi.subSystemClass.annotations.filter [ a |
			a.type.name == "Gnuplot"
		].head

		val defaultFontsize = 10

		// TODO: error checking
		val format = plotAnnotation?.getAttribute("format")?.asString
		val outputfile = plotAnnotation?.getAttribute("outputfile")?.asString
		val width = plotAnnotation?.getAttribute("width")?.asInteger
		val height = plotAnnotation?.getAttribute("height")?.asInteger
		val fontsize = plotAnnotation?.getAttribute("fontsize")?.asInteger ?: defaultFontsize

		val graphAnnotations = ssi.subSystemClass.annotations.filter [ a |
			a.type.name == "GnuplotGraph"
		].toList

		'''
			#!/gnuplot
			
			# Color Brewer set1 5-set
			set linetype 1 lc rgb '#e41a1c' lw 1
			set linetype 2 lc rgb '#377eb8' lw 1
			set linetype 3 lc rgb '#4daf4a' lw 1
			set linetype 4 lc rgb '#984ea3' lw 1
			set linetype 5 lc rgb '#ff7f00' lw 1
			set linetype cycle 5
			
			cd 'log'
			set datafile separator comma
			set terminal «format» size «width»,«height» font ",«fontsize»" background "white"
			set output '«outputfile»'
			set size 1,1
			set multiplot layout «graphAnnotations.size»,1
			set grid
			show grid
			set format y "% 5.3f"
			«var i = 0»
			«FOR a : graphAnnotations»
				
				«ssi.generateGraph(a, i++, graphAnnotations.size)»
			«ENDFOR»
			
			unset multiplot
			unset output
			
		'''
	}

	def protected generateGraph(SubSystemInstance ssi, Annotation graph, int index, int total) {

		// TODO: handle multiple paths in the same graph
		val paths = graph.getAttribute("paths")?.asString

		// TODO: take interval from physical thread associated with actor instance instead of annotation attribute
		val interval = graph.getAttribute("interval")?.asInteger ?: 20
		val xtics = graph.getAttribute("xtics")?.asReal ?: 100
		val mxtics = graph.getAttribute("mxtics")?.asInteger ?: 4
		val ymin = graph.getAttribute("ymin")?.asReal
		val ymax = graph.getAttribute("ymax")?.asReal

		val vertOrigin = ((total - (index + 1)) as double) / total
		val vertSize = 1.0F / total

		'''
			set yrange [«ymin ?: "*"» : «ymax ?: "*"»]
			set xtics rotate «xtics»
			set mxtics «mxtics»
			set ylabel
			set xlabel "time (ms)"
			timeInMs(x) = «interval» * x
			set origin 0,«vertOrigin»
			set size 1,«vertSize»
			plot 'main.data.csv' using (timeInMs(column(1))):(column("«paths»")) with lines
		'''
	}
}

Back to the top