Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix Radar plot #664

Merged
merged 14 commits into from
May 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion local_setup_scripts/rebuild_sr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sleep 5
docker volume rm -f osdata || true
docker volume rm -f dbdata || true
docker image rm 127.0.0.1:5000/openstudio-server -f
docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.2.0
docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.4.0
docker push 127.0.0.1:5000/openstudio-server
cd docker/R/
#docker image rm 127.0.0.1:5000/openstudio-rserve -f
Expand Down
2 changes: 1 addition & 1 deletion local_setup_scripts/win64/rebuild_sr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sleep 5
docker volume rm -f osdata || true
docker volume rm -f dbdata || true
docker image rm 127.0.0.1:5000/openstudio-server -f
docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.2.0
docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.4.0
docker push 127.0.0.1:5000/openstudio-server
cd docker/R
#docker image rm 127.0.0.1:5000/openstudio-rserve -f
Expand Down
2 changes: 1 addition & 1 deletion local_setup_scripts/win64/rebuild_sr_no_rm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sleep 5
docker volume rm -f osdata || true
docker volume rm -f dbdata || true
#docker image rm 127.0.0.1:5000/openstudio-server -f
docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.2.0
docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.4.0
docker push 127.0.0.1:5000/openstudio-server
cd docker/R
#docker image rm 127.0.0.1:5000/openstudio-rserve -f
Expand Down
2 changes: 1 addition & 1 deletion server/app/assets/javascripts/radarchart.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var RadarChart = {
var allAxis = (d[0].map(function(i, j){return i.axis}));
var total = allAxis.length;
var radius = cfg.factor*Math.min(cfg.w/2, cfg.h/2);
var Format = d3.format('%');
var Format = d3.format('.2s');
d3.select(id).select("svg").remove();

var g = d3.select(id)
Expand Down
4 changes: 4 additions & 0 deletions server/app/assets/stylesheets/main.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@ h2.header-large {
}
}

.sig-fig {
padding-top: 5px;
}

//remove this if you want traditional pagination
.pagination {
background: #f9f9f9;
Expand Down
65 changes: 45 additions & 20 deletions server/app/controllers/analyses_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,18 @@ def index
# GET /analyses/1
# GET /analyses/1.json
def show
logger.info "analyses_contoller.show enter"
logger.info "analyses_controller.show enter"
# for pagination
per_page = 50

@analysis = Analysis.find(params[:id])

if params[:commit] && params[:commit] == 'Update'
# update # of significant digits
@analysis.significant_digits = params[:significant_digits].to_i
@analysis.save!
end

if @analysis

@has_obj_targets = @analysis.variables.where(:objective_function_target.ne => nil).count > 0
Expand All @@ -78,7 +84,7 @@ def show
unless params[:status].nil?
@status = params[:status]
end

# blanks should be saved as nil or it will crash
@all_page = @status == 'all' ? params[:page] : params[:all_page]
@all_page = @all_page == '' ? 1 : @all_page
Expand Down Expand Up @@ -136,7 +142,7 @@ def show
format.json { render json: { analysis: @analysis } }
format.js
end
logger.info "analyses_contoller.show leave"
logger.info "analyses_controller.show leave"
end

# GET /analyses/new
Expand Down Expand Up @@ -500,6 +506,12 @@ def plot_parallelcoordinates
@include_all = true
end

#change display name type
if params[:commit] && params[:commit] == 'Change Display Name'
@analysis.variable_display_name_choice = params[:variable_display_name_choice]
@analysis.save!
end

# figure out actions
# if params[:commit] && params[:commit] == 'All Data'
# don't do pareto
Expand All @@ -521,6 +533,7 @@ def plot_parallelcoordinates

# Interactive XY plot: choose x and y variables
def plot_xy_interactive
logger.debug "plot_xy_interactive params: #{params}"
@analysis = Analysis.find(params[:id])
@saved_paretos = @analysis.paretos

Expand All @@ -547,6 +560,12 @@ def plot_xy_interactive
@variables = [pareto.x_var, pareto.y_var]
end

#change display name type
if params[:commit] && params[:commit] == 'Change Display Name'
@analysis.variable_display_name_choice = params[:variable_display_name_choice]
@analysis.save!
end

# calculate pareto or update chart?
if params[:commit] && params[:commit] == 'Calculate Pareto Front'
# set variable for view
Expand Down Expand Up @@ -670,32 +689,23 @@ def plot_radar
end
end

# Bar chart (single datapoint, must have objective functions)
# "% error"-like, but negative when actual is less than target and positive when it is more than target
def plot_bar
@analysis = Analysis.find(params[:id])
@datapoint = DataPoint.find(params[:datapoint_id])

respond_to do |format|
format.html # plot_bar.html.erb
end
end

# This function provides all data (plot or export data, depending on what is specified) in
# a JSON format that can be consumed by various users such as the bar plots, parallel plots, pairwise plots, etc.
def analysis_data
@analysis = Analysis.find(params[:id])
datapoint_id = params[:datapoint_id] || nil
logger.debug "analyses_data params: #{params}"
# other variables that can be specified
options = {}
options['visualize'] = params[:visualize] == 'true'
options['export'] = params[:export] == 'true'
options['pivot'] = params[:pivot] == 'true'
options['perturbable'] = params[:perturbable] == 'true'

logger.debug "analyses_data options: #{options}"
# get data
@variables, @data = get_analysis_data(@analysis, datapoint_id, true, options)

logger.debug "analyses_data @variables: #{@variables}"
logger.debug "analyses_data @data: #{@data}"
logger.info 'sending analysis data to view'
respond_to do |format|
format.json { render json: { variables: @variables, data: @data } }
Expand Down Expand Up @@ -885,8 +895,10 @@ def get_analysis_data(analysis, datapoint_id = nil, only_completed_normal = true
options.each do |k, v|
or_qry << { :"#{k}" => v } if v
end
variables = Variable.where(analysis_id: analysis, :name.nin => ['', nil]).or(or_qry)
logger.debug "get_analysis_data or_qry: #{or_qry}"
variables = Variable.where(analysis_id: analysis, :name.exists => true, :name.ne => '').any_of(or_qry)
.order_by([:pivot.desc, :perturbable.desc, :output.desc, :name.asc]).as_json(only: var_fields)
logger.debug "get_analysis_data variables: #{variables.to_a}"

# Create a map from the _id to the variables machine name
variable_name_map = Hash[variables.map { |v| [v['_id'], v['name'].tr('.', '|')] }]
Expand Down Expand Up @@ -938,11 +950,21 @@ def get_analysis_data(analysis, datapoint_id = nil, only_completed_normal = true
}

# Eventually use this where the timestamp is processed as part of the request to save time
logger.info "datapoint_id.size: #{datapoint_id.size}" if !datapoint_id.nil?
logger.info "datapoint_id.class: #{datapoint_id.class}"
plot_data = if datapoint_id
if only_completed_normal
DataPoint.where(analysis_id: analysis, status: 'completed', :id.in => datapoint_id, status_message: 'completed normal')
if datapoint_id.class == Array
DataPoint.where(analysis_id: analysis, status: 'completed', :id.in => datapoint_id, status_message: 'completed normal')
else
DataPoint.where(analysis_id: analysis, status: 'completed', :id => datapoint_id, status_message: 'completed normal')
end
else
DataPoint.where(analysis_id: analysis, :id.in => datapoint_id)
if datapoint_id.class == Array
DataPoint.where(analysis_id: analysis, :id.in => datapoint_id)
else
DataPoint.where(analysis_id: analysis, :id => datapoint_id)
end
end
else
if only_completed_normal
Expand Down Expand Up @@ -999,7 +1021,10 @@ def get_analysis_data(analysis, datapoint_id = nil, only_completed_normal = true
# Get plot variables
# Used by plot_parallelcoordinates
def get_plot_variables(analysis)
variables = Variable.where(analysis_id: analysis).or(perturbable: true).or(pivot: true).or(visualize: true).order_by(:name.asc)
any_of_qry = [{ perturbable: true }, { pivot: true }, { visualize: true }]
variables = Variable.where(analysis_id: analysis).any_of(any_of_qry).order_by(:name.asc)
logger.debug "GET_PLOT_VARIABLES: #{variables.to_a}"
variables
end

def write_and_send_csv(analysis, datapoint_ids = nil)
Expand Down
4 changes: 3 additions & 1 deletion server/app/models/analysis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Analysis
field :download_osm, type: Boolean, default: true
field :download_osw, type: Boolean, default: true
field :download_reports, type: Boolean, default: true
field :variable_display_name_choice, type: String, default: 'display_name'

# Hash of the jobs to run for the analysis
# field :jobs, type: Array, default: [] # very specific format
Expand All @@ -79,6 +80,7 @@ class Analysis

# Temp location for these vas
field :samples, type: Integer
field :significant_digits, type: Integer, default: 3

has_mongoid_attached_file :seed_zip,
url: '/assets/analyses/:id/:style/:basename.:extension',
Expand Down Expand Up @@ -328,7 +330,7 @@ def superset_of_input_variables
# sort before sending back
Hash[mappings.sort_by { |_, v| v }]
end

# filter results on analysis show page (per status)
def search(search, status, page_no = 1, view_all = 0)
page_no = page_no.presence || 1
Expand Down
2 changes: 1 addition & 1 deletion server/app/models/variable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ def self.get_variable_data_v2(analysis)
:perturbable, :pivot, :output, :visualize, :export, :static_value, :minimum, :maximum,
:objective_function, :objective_function_group, :objective_function_index, :objective_function_target
]
variables = Variable.where(analysis_id: analysis).or({ perturbable: true }, { pivot: true }, { output: true }, export: true).as_json(only: save_fields)
variables = Variable.where(analysis_id: analysis).any_of([{ perturbable: true }, { pivot: true }, { output: true }, { export: true }]).as_json(only: save_fields)

# Add in some measure information into each of the variables, if it is a variable
variables.each do |v|
Expand Down
67 changes: 39 additions & 28 deletions server/app/views/analyses/_table.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -66,33 +66,45 @@
<div class="row-fluid">
<div class="table-pad">
<!--toggle obj function is there are more than 3-->

<% class_var = "" %>
<% if @objective_functions.count > 3 %>
<div class="button-container">
<button class="btn btn-mini" id='<%= "toggle-button-#{status || ''}"%>'>Toggle Obj Functions</button>
<% class_var = "obj-function-col-" + status %>
</div>
<% end %>

<!--toggle view_all on ALL page -->
<br/>

<% if status == 'all' and @view_all == 0 %>
<div class="button-container">
<%= link_to("View All", analysis_path(:id => @analysis, :view_all => 1, :status => status,
:all_page => all_page, :completed_page => completed_page,
:started_page => started_page, :queued_page => queued_page,
:na_page => na_page), :class => "btn btn-mini") %></button>
</div>
<% elsif status == 'all' and @view_all == 1 %>
<div class="button-container">
<%= link_to("Paginate", analysis_path(:id => @analysis.id, :status => status,
:view_all => 0), :class => "btn btn-mini") %>
<div>
<% class_var = "" %>
<% if @objective_functions.count > 1 %>

<div class="span4">
<div class="button-container">
<button class="btn btn-mini" id='<%= "toggle-button-#{status || ''}"%>'>Toggle Obj Functions</button>
<% class_var = "obj-function-col-" + status %>
</div>
</div>
<div class="span6">
<div class="sig-fig">
<%= form_tag analysis_path(@analysis), :method => 'get' do %>
<%= label_tag significant_digits, "Obj Func Significant Digits" %>
<%= number_field_tag "significant_digits", significant_digits %>
<%= submit_tag "Update" %>
<% end %>
</div>
</div>
<% end %>
<div class="span2">
<!--toggle view_all on ALL page -->
<% if status == 'all' and @view_all == 0 %>
<div class="button-container">
<%= link_to("View All", analysis_path(:id => @analysis, :view_all => 1, :status => status,
:all_page => all_page, :completed_page => completed_page,
:started_page => started_page, :queued_page => queued_page,
:na_page => na_page), :class => "btn btn-mini") %></button>
</div>
<% elsif status == 'all' and @view_all == 1 %>
<div class="button-container">
<%= link_to("Paginate", analysis_path(:id => @analysis.id, :status => status,
:view_all => 0), :class => "btn btn-mini") %>
</div>
<% end %>
</div>
<% end %>
</div>

<table id="datapointtable_<%= status%>" class="tablesorter table table-striped">
<table id="datapointtable_<%= status%>" class="tablesorter table table-striped pad-top">
<thead>
<tr>
<th>Name</th>
Expand All @@ -118,8 +130,8 @@
<!-- TODO: This is horrible. Can we use an ostruct? send the data from the contoller -->
<td class="<%= class_var %>">
<% if dp.results[ov['name'].split(".")[0]] && dp.results[ov['name'].split(".")[0]][ov['name'].split(".")[1]] %>
<% if dp.results[ov['name'].split(".")[0]][ov['name'].split(".")[1]] =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/ %>
<%= dp.results[ov['name'].split(".")[0]][ov['name'].split(".")[1]].round(2) %>
<% if dp.results[ov['name'].split(".")[0]][ov['name'].split(".")[1]].class != String && !@analysis.significant_digits.nil? %>
<%= dp.results[ov['name'].split(".")[0]][ov['name'].split(".")[1]].round(@analysis.significant_digits) %>
<% else %>
<%= dp.results[ov['name'].split(".")[0]][ov['name'].split(".")[1]] %>
<% end %>
Expand All @@ -135,7 +147,6 @@
| <%= link_to 'Zip File', download_result_file_data_point_path(dp, filename: h.attachment.original_filename) %>
<% end %>
<% if dp.status == 'completed' && @has_obj_targets %>
| <%= link_to('Bar Chart', plot_bar_analysis_path(:id => @analysis.id, :datapoint_id => dp.id)) %>
| <%= link_to('Radar Plot', plot_radar_analysis_path(:id => @analysis.id, :datapoint_id => dp.id)) %>
<% end %>
<td class="other-col"><%= link_to 'Destroy', dp, method: :delete, data: {confirm: 'Are you sure?'} %></td>
Expand Down