1#include "EMTElementForm.h"
2#include "../elements/powerElement/EMTElement.h"
3#include "../editors/ChartView.h"
4#include "../editors/Workspace.h"
5#include "../extLibs/fftw/fftw3.h"
6#include "ATPFileEditorForm.h"
8#include <wx/wfstream.h>
11#include <wx/process.h>
13EMTElementForm::EMTElementForm(wxWindow* parent,
EMTElement* emtElement)
14 : EMTElementFormBase(parent), m_parent(parent), m_emtElement(emtElement)
16 m_staticTextNode->SetLabel(m_staticTextNode->GetLabel() + wxT(
" (3\u0278)"));
18 auto data = m_emtElement->GetEMTElementData();
19 m_textCtrlName->SetValue(data.name);
20 m_filePickerATPFile->SetPath(data.atpFile.GetFullPath());
21 LoadNodes(data.atpFile.GetFullPath());
22 m_choiceNodes->SetSelection(m_choiceNodes->FindString(data.atpNodeName));
23 m_textCtrlStepSize->SetValue(wxString::Format(wxT(
"%e"), data.stepSize));
24 m_spinCtrlCyclesToSS->SetValue(data.cyclesToSS);
25 m_textCtrlRecFreq->SetValue(wxString::Format(wxT(
"%d"), data.recordFrequency));
26 m_checkBoxUseFilter->SetValue(data.useMedianFilter);
27 m_spinCtrlMaxNumHarmonics->SetValue(data.numMaxHarmonics);
28 m_textCtrlHarmThreshold->SetValue(wxString::Format(wxT(
"%.2f"), data.harmonicsThreshold));
30 m_properties =
static_cast<Workspace*
>(parent)->GetProperties();
32 SetSize(DoGetBestSize());
35EMTElementForm::~EMTElementForm()
39bool EMTElementForm::ValidateData()
41 wxFileName fileName(m_filePickerATPFile->GetPath());
42 if (!fileName.IsOk()) {
43 wxMessageDialog msgDialog(m_parent, _(
"The ATP file doesn't exist. Insert the correct path."), _(
"Error"), wxOK | wxCENTRE | wxICON_ERROR);
44 msgDialog.ShowModal();
47 double stepSize = 0.0;
48 if (!m_textCtrlStepSize->GetValue().ToDouble(&stepSize)) {
49 wxMessageDialog msgDialog(m_parent, _(
"The step size must be a number."), _(
"Error"), wxOK | wxCENTRE | wxICON_ERROR);
50 msgDialog.ShowModal();
54 if (!m_textCtrlRecFreq->GetValue().ToLong(&recFreq)) {
55 wxMessageDialog msgDialog(m_parent, _(
"The steps to record data must be an integer number."), _(
"Error"), wxOK | wxCENTRE | wxICON_ERROR);
56 msgDialog.ShowModal();
59 if (m_choiceNodes->GetSelection() == wxNOT_FOUND) {
60 wxMessageDialog msgDialog(m_parent, _(
"No connection node selected."), _(
"Error"), wxOK | wxCENTRE | wxICON_ERROR);
61 msgDialog.ShowModal();
64 double harmThreshold = 0.0;
65 if (!m_textCtrlHarmThreshold->GetValue().ToDouble(&harmThreshold)) {
66 wxMessageDialog msgDialog(m_parent, _(
"The threshold to detect harmonics must be a number."), _(
"Error"), wxOK | wxCENTRE | wxICON_ERROR);
67 msgDialog.ShowModal();
71 auto data = m_emtElement->GetEMTElementData();
72 data.name = m_textCtrlName->GetValue();
73 data.atpFile = m_filePickerATPFile->GetPath();
74 data.atpNodeName = m_choiceNodes->GetString(m_choiceNodes->GetSelection());
75 data.stepSize = stepSize;
76 data.cyclesToSS = m_spinCtrlCyclesToSS->GetValue();
77 data.recordFrequency = recFreq;
78 data.useMedianFilter = m_checkBoxUseFilter->GetValue();
79 data.numMaxHarmonics = m_spinCtrlMaxNumHarmonics->GetValue();
80 data.harmonicsThreshold = harmThreshold;
82 m_emtElement->SetEMTElementData(data);
87void EMTElementForm::OnCancelClick(wxCommandEvent& event)
89 EndModal(wxID_CANCEL);
91void EMTElementForm::OnOKClick(wxCommandEvent& event)
93 if (ValidateData()) EndModal(wxID_OK);
96void EMTElementForm::LoadNodes(wxString atpFilePath)
98 wxArrayString atpFile;
99 wxTextFile file(atpFilePath);
100 if (!file.Exists())
return;
102 if (file.Open(atpFilePath)) {
103 atpFile.Add(file.GetFirstLine());
106 atpFile.Add(file.GetNextLine());
110 wxArrayString nodeList = m_emtElement->GetATPNodes(atpFile);
111 m_choiceNodes->Clear();
112 m_choiceNodes->Append(nodeList);
115void EMTElementForm::OnEditATPFileClick(wxCommandEvent& event)
117 wxFileName fileName(m_filePickerATPFile->GetPath());
118 if (!fileName.IsOk()) {
119 wxMessageDialog msgDialog(m_parent, _(
"The ATP file doesn't exist. Insert the correct path."), _(
"Error"), wxOK | wxCENTRE | wxICON_ERROR);
120 msgDialog.ShowModal();
124 atpFileEditorForm.SetSize(800, 600);
125 atpFileEditorForm.ShowModal();
128void EMTElementForm::OnTestClick(wxCommandEvent& event)
130 if (ValidateData()) {
132 m_emtElement->UpdateData(m_properties);
133 if (!m_emtElement->CalculateCurrent(errorMsg,
true)) {
134 wxMessageDialog msgDialog(m_parent, errorMsg, _(
"Error"), wxOK | wxCENTRE | wxICON_ERROR);
135 msgDialog.ShowModal();
138 std::vector<double> time, in, timeSamp, inSamp, outR, outI, outM, outP, freq;
139 auto atpData = m_emtElement->GetEMTElementData().atpData;
140 auto inFFTData = m_emtElement->GetEMTElementData().inFFTData;
141 auto outFFTData = m_emtElement->GetEMTElementData().outFFTData;
142 for (
auto data : atpData) {
143 time.emplace_back(data.first);
144 in.emplace_back(data.second);
146 for (
auto data : inFFTData) {
147 timeSamp.emplace_back(data.first);
148 inSamp.emplace_back(data.second);
150 for (
auto data : outFFTData) {
151 outR.emplace_back(data.second.real());
152 outI.emplace_back(data.second.imag());
153 outM.emplace_back(abs(data.second));
154 outP.emplace_back(arg(data.second) * 180.0 / M_PI);
155 freq.emplace_back(data.first);
159 std::vector<double> currMag, currPha, harmOrder;
160 auto harmData = m_emtElement->GetEMTElementData().currHarmonics;
167 for(
auto const& data : harmData){
168 currMag.emplace_back(abs(data.second));
169 currPha.emplace_back(arg(data.second) * 180.0 / M_PI);
170 harmOrder.emplace_back(
static_cast<double>(data.first));
173 std::vector<ElementPlotData> plotDataList;
174 ElementPlotData plotATPData(_(
"ATP Output"), ElementPlotData::CurveType::CT_TEST);
175 ElementPlotData plotFFTData(_(
"Fourier Analysis"), ElementPlotData::CurveType::CT_TEST);
176 ElementPlotData plotCurrData(_(
"Current Phasor"), ElementPlotData::CurveType::CT_TEST);
178 plotATPData.AddData(in, _(
"Data"));
180 plotFFTData.AddData(inSamp, _(
"Input"));
181 plotFFTData.AddData(timeSamp, _(
"Time Sampled"));
182 plotFFTData.AddData(outR, _(
"Real"));
183 plotFFTData.AddData(outI, _(
"Imaginary"));
184 plotFFTData.AddData(outM, _(
"Magnitude"));
185 plotFFTData.AddData(outP, _(
"Phase"));
186 plotFFTData.AddData(freq, _(
"Frequency"));
188 plotCurrData.AddData(currMag, _(
"Magnitude"));
189 plotCurrData.AddData(currPha, _(
"Phase"));
190 plotCurrData.AddData(harmOrder, _(
"Harmonic Order"));
192 plotDataList.push_back(plotATPData);
193 plotDataList.push_back(plotFFTData);
194 plotDataList.push_back(plotCurrData);
195 ChartView* cView =
new ChartView(
this, plotDataList, time, m_properties->GetGeneralPropertiesData().plotLib);
199void EMTElementForm::OnATPFileChange(wxFileDirPickerEvent& event)
201 LoadNodes(m_filePickerATPFile->GetPath());
This class is responsible to manage the charts generated in the transient electromechanical studies.
Element to connect ATP-EMTP.
This class manages the graphical and power elements. It is responsible for handling the user's intera...