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,
Workspace* workspace)
14 : EMTElementFormBase(parent), m_parent(parent), m_emtElement(emtElement), m_workspace(workspace)
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 = workspace->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, Mode::Both,
true,
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 std::vector <double> timeThreePhase, currentA, currentB, currentC;
140 std::vector <double> magIa, magIb, magIc, angIa, angIb, angIc;
142 auto inFFTData = m_emtElement->GetEMTElementData().inFFTData;
143 auto outFFTData = m_emtElement->GetEMTElementData().outFFTData;
148 for (
auto& data : m_emtElement->GetEMTElementData().atpSampleData)
150 time.emplace_back(data.t);
151 currentA.emplace_back(data.current[0]);
152 currentB.emplace_back(data.current[1]);
153 currentC.emplace_back(data.current[2]);
154 magIa.emplace_back(data.mag[0]);
155 magIb.emplace_back(data.mag[1]);
156 magIc.emplace_back(data.mag[2]);
157 angIa.emplace_back(data.angle[0] * 180.0 / M_PI);
158 angIb.emplace_back(data.angle[1] * 180.0 / M_PI);
159 angIc.emplace_back(data.angle[2] * 180.0 / M_PI);
162 for (
auto data : inFFTData) {
163 timeSamp.emplace_back(data.first);
164 inSamp.emplace_back(data.second);
166 for (
auto data : outFFTData) {
167 outR.emplace_back(data.second.real());
168 outI.emplace_back(data.second.imag());
169 outM.emplace_back(abs(data.second));
170 outP.emplace_back(arg(data.second) * 180.0 / M_PI);
171 freq.emplace_back(data.first);
175 std::vector<double> currMag, currPha, harmOrder;
176 auto harmData = m_emtElement->GetEMTElementData().currHarmonics;
183 for (
auto const& data : harmData) {
184 currMag.emplace_back(abs(data.second));
185 currPha.emplace_back(arg(data.second) * 180.0 / M_PI);
186 harmOrder.emplace_back(
static_cast<double>(data.first));
189 std::vector<ElementPlotData> plotDataList;
191 ElementPlotData plot3PATPData(_(
"ATP Three-phase output"), ElementPlotData::CurveType::CT_TEST);
192 ElementPlotData plotFFTData(_(
"Fourier Analysis"), ElementPlotData::CurveType::CT_TEST);
193 ElementPlotData plotCurrData(_(
"Current Phasor"), ElementPlotData::CurveType::CT_TEST);
197 plot3PATPData.AddData(currentA, _(
"Phase A Current"));
198 plot3PATPData.AddData(currentB, _(
"Phase B Current"));
199 plot3PATPData.AddData(currentC, _(
"Phase C Current"));
200 plot3PATPData.AddData(magIa, _(
"Magnitude A Current"));
201 plot3PATPData.AddData(magIb, _(
"Magnitude B Current"));
202 plot3PATPData.AddData(magIc, _(
"Magnitude C Current"));
203 plot3PATPData.AddData(angIa, _(
"Angle A Current"));
204 plot3PATPData.AddData(angIb, _(
"Angle B Current"));
205 plot3PATPData.AddData(angIc, _(
"Angle C Current"));
206 plot3PATPData.AddData(timeThreePhase, _(
"Time 3f"));
208 plotFFTData.AddData(inSamp, _(
"Input"));
209 plotFFTData.AddData(timeSamp, _(
"Time Sampled"));
210 plotFFTData.AddData(outR, _(
"Real"));
211 plotFFTData.AddData(outI, _(
"Imaginary"));
212 plotFFTData.AddData(outM, _(
"Magnitude"));
213 plotFFTData.AddData(outP, _(
"Phase"));
214 plotFFTData.AddData(freq, _(
"Frequency"));
216 plotCurrData.AddData(currMag, _(
"Magnitude"));
217 plotCurrData.AddData(currPha, _(
"Phase"));
218 plotCurrData.AddData(harmOrder, _(
"Harmonic Order"));
221 plotDataList.push_back(plot3PATPData);
222 plotDataList.push_back(plotFFTData);
223 plotDataList.push_back(plotCurrData);
226 auto& cwMngr = m_workspace->GetChartWindowManager();
227 cwMngr.Open(plotDataList, time);
230void EMTElementForm::OnATPFileChange(wxFileDirPickerEvent& event)
232 LoadNodes(m_filePickerATPFile->GetPath());
Element to connect ATP-EMTP.
This class manages the graphical and power elements. It is responsible for handling the user's intera...