From 338bdca0655f5a10ea13d43db776242d9466c042 Mon Sep 17 00:00:00 2001 From: xiyehu2 <xiyehu2@illinois.edu> Date: Mon, 23 Oct 2023 12:13:16 -0500 Subject: [PATCH] stable build --- Cpp/CMakeLists.txt | 2 +- Cpp/lib/AWG.cpp | 42 +----- Cpp/lib/AWG.h | 8 +- Cpp/lib/CMakeLists.txt | 18 +-- Cpp/lib/external/CMakeLists.txt | 8 - Cpp/lib/waveform.cpp | 252 ++++++++++++++++++++------------ Cpp/lib/waveform.h | 85 ++++++----- 7 files changed, 224 insertions(+), 191 deletions(-) diff --git a/Cpp/CMakeLists.txt b/Cpp/CMakeLists.txt index 1636af2..98f785b 100644 --- a/Cpp/CMakeLists.txt +++ b/Cpp/CMakeLists.txt @@ -24,5 +24,5 @@ set(LIBS # main.exe project ("main") -add_executable(main run.cpp) +add_subdirectory(src) target_link_libraries(main ${LIBS}) diff --git a/Cpp/lib/AWG.cpp b/Cpp/lib/AWG.cpp index 44c76b7..3c64736 100644 --- a/Cpp/lib/AWG.cpp +++ b/Cpp/lib/AWG.cpp @@ -32,40 +32,6 @@ void AWG::checkError() { } } -//void* AWG::getPageAlignedMem(uint64 memSize) { -// /** -// * returns a pointer to a page aligned mem location. -// * -// * @param memSize size of memory to allocate, bytes -// * @return pointer to start of a page aligned mem location -// */ -// -// // for unknown reasons VirtualAlloc/VirtualFree leaks memory if memSize < 4096 (page size) -// // therefore use _aligned_malloc () to get small amounts of page aligned memory -// if (memSize >= 4096) -// return VirtualAlloc(NULL, (size_t)memSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); -// else { -// void* pMem = _aligned_malloc((size_t)memSize, 4096); -// if (pMem == NULL) -// return NULL; -// memset(pMem, 0, (size_t)memSize); -// return pMem; -// } -//} -// -//void AWG::freePageAlignedMem(void* pMem, uint64 memSize) { -// /** -// * frees a page aligned memory space. -// * -// * @param pMem pointer to a page aligned memory location -// * @param memSize memory size in bytes to deallocate -// */ -// if (memSize >= 4096) -// VirtualFree(pMem, 0, MEM_RELEASE); -// else -// _aligned_free(pMem); -//} -// void AWG::open(int openIndex) { if (this->isOpen()) { std::cout << "card already opened" << std::endl; @@ -714,7 +680,8 @@ void AWG::setSeqModeStep( uint64 segment, uint64 nextStep, uint64 nLoop, - SEQ_LOOPCONDITION condition) { + SEQ_LOOPCONDITION condition +) { if (!this->isOpen()) { return; } int64 mask = (uint64(condition) << 32) @@ -729,9 +696,10 @@ void AWG::setSeqModeStep( } void AWG::writeSeqModeSegment( + int segment, void* pDataBuffer, - int size, - int segment) { + int size +) { if (!this->isOpen()) { return; } spcm_dwSetParam_i32( this->pCardHandle, diff --git a/Cpp/lib/AWG.h b/Cpp/lib/AWG.h index 4a21a20..73edc46 100644 --- a/Cpp/lib/AWG.h +++ b/Cpp/lib/AWG.h @@ -228,6 +228,7 @@ public: * @param ch channel index * @param amp amplitude (mV) * @param stopLvl enum CHANNEL_STOPLVL: ZERO, LOW, HIGH, HOLDLAST + * @param enable enable/disable channel output */ void setChannel(int ch, int amp, CHANNEL_STOPLVL stopLvl, bool enable); @@ -445,6 +446,7 @@ public: * @param step step to configure * @param segment memory segment step is associated with * @param nextStep index of next step after end loop condition is met + * @param nLoop number of loop the memory segment is replayed * @param condition end loop condition, enum SEQ_LOOPCONDITION */ void setSeqModeStep( @@ -458,14 +460,14 @@ public: /** * @brief write buffered data into a memory segment in sequence replay mode. * + * @param segment memory segment to write to * @param pDataBuffer pointer to data memory, must be page aligned * @param size size of data buffer in number of samples - * @param segment memory segment to write to */ void writeSeqModeSegment( + int segment, void* pDataBuffer, - int size, - int segment + int size ); // ---------------------data transfer--------------------- diff --git a/Cpp/lib/CMakeLists.txt b/Cpp/lib/CMakeLists.txt index f1c7210..26f0bbc 100644 --- a/Cpp/lib/CMakeLists.txt +++ b/Cpp/lib/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(external) -find_package(Eigen3 3.4 REQUIRED) +# find_package(Eigen3 3.4 REQUIRED) target_sources(wfmLib PRIVATE waveform.cpp @@ -8,9 +8,9 @@ target_sources(wfmLib waveform.h CSVhelper.hpp ) -target_link_libraries(wfmLib - Eigen3::Eigen -) +# target_link_libraries(wfmLib + # Eigen3::Eigen +# ) # target_link_libraries(wfmLib helperLib) target_sources(AWGLib @@ -19,10 +19,10 @@ target_sources(AWGLib PUBLIC AWG.h ) -add_library(driverLib STATIC IMPORTED) -set_target_properties(driverLib PROPERTIES - IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/driver_header/spcm_win64_msvcpp.lib" - INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/driver_header" -) +# add_library(driverLib STATIC IMPORTED) +# set_target_properties(driverLib PROPERTIES +# IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/driver_header/spcm_win64_msvcpp.lib" +# INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/driver_header" +# ) diff --git a/Cpp/lib/external/CMakeLists.txt b/Cpp/lib/external/CMakeLists.txt index da2c4db..e69de29 100644 --- a/Cpp/lib/external/CMakeLists.txt +++ b/Cpp/lib/external/CMakeLists.txt @@ -1,8 +0,0 @@ -# target_sources(tomlLib -# PRIVATE -# toml.cpp -# PUBLIC -# toml.hpp -# ) - -# target_include_directories(tomlLib PUBLIC ${CMAKE_CURRENT_LIST_DIR}) \ No newline at end of file diff --git a/Cpp/lib/waveform.cpp b/Cpp/lib/waveform.cpp index ac50e0f..11d06c2 100644 --- a/Cpp/lib/waveform.cpp +++ b/Cpp/lib/waveform.cpp @@ -5,82 +5,99 @@ #include <vector> #include <string> #include <numeric> +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> -ArrayWaveform::ArrayParam::ArrayParam() { - this->samplingRate = 0; - this->freqResolution = 0; -} +ArrayWaveform::ArrayWaveform() {} -ArrayWaveform::ArrayParam::ArrayParam(const ArrayParam& other) { - this->samplingRate = other.samplingRate; - this->freqResolution = other.freqResolution; - this->freqTones = other.freqTones; - this->phases = other.phases; - this->amplitudes = other.amplitudes; -} +ArrayWaveform::~ArrayWaveform() { unbindBuffer(); } + +void* ArrayWaveform::getDataBuffer() { return this->pDataBuffer; } -void ArrayWaveform::ArrayParam::setSamplingRate(unsigned long sr) { - this->samplingRate = sr; +int64_t ArrayWaveform::getDataLen() { return this->dataLen; } + +void ArrayWaveform::setSamplingRate(ulong sr) { + this->wfmParam.samplingRate = sr; } -void ArrayWaveform::ArrayParam::setFreqResolution(unsigned long fr) { - this->freqResolution = fr; +ulong ArrayWaveform::getSamplingRate() { return this->wfmParam.samplingRate; } + +void ArrayWaveform::setFreqResolution(ulong fr) { + this->wfmParam.freqResolution = fr; } -void ArrayWaveform::ArrayParam::setFreqTone( +ulong ArrayWaveform::getFreqResolution() { return this->wfmParam.freqResolution; } + +void ArrayWaveform::setFreqTone( int centerFreq, int freqSpacing, int numTones ) { int freqStart = centerFreq - freqSpacing * int(std::floor(numTones / 2)); - this->freqTones.setLinSpaced( + this->wfmParam.freqTones.setLinSpaced( numTones, freqStart, freqStart + freqSpacing * (numTones-1) ); } -void ArrayWaveform::ArrayParam::setFreqTone(const Eigen::VectorXd& tones) { - this->freqTones.resize(0); - this->freqTones.resize(tones.size()); - this->freqTones = tones; +void ArrayWaveform::setFreqTone(const std::vector<int>& tones) { + this->wfmParam.freqTones.resize(tones.size()); + for (auto i = 0; i < tones.size(); i++) { + this->wfmParam.freqTones[i] = tones[i]; + } } -Eigen::VectorXd ArrayWaveform::ArrayParam::getFreqTone() { - return this->freqTones; +std::vector<double> ArrayWaveform::getFreqTone() { + std::vector<double> v( + this->wfmParam.freqTones.data(), + this->wfmParam.freqTones.data() + this->wfmParam.freqTones.size() + ); + return v; } -void ArrayWaveform::ArrayParam::setPhase(const Eigen::VectorXd& phases) { - this->phases.resize(0); - this->phases.resize((phases.size())); - this->phases = phases; +void ArrayWaveform::setPhase(const std::vector<double>& phases) { + this->wfmParam.phases.resize(phases.size()); + for (auto i = 0; i < phases.size(); i++) { + this->wfmParam.phases[i] = phases[i]; + } } -Eigen::VectorXd ArrayWaveform::ArrayParam::getPhase() { - return this->phases; +std::vector<double> ArrayWaveform::getPhase() { + std::vector<double> v( + this->wfmParam.phases.data(), + this->wfmParam.phases.data() + this->wfmParam.phases.size() + ); + return v; } -void ArrayWaveform::ArrayParam::setAmplitude(const Eigen::VectorXd& amplitudes) { - this->amplitudes.resize(0); - this->amplitudes.resize(amplitudes.size()); - this->amplitudes = amplitudes; +void ArrayWaveform::setAmplitude(const std::vector<double>& amplitudes) { + this->wfmParam.amplitudes.resize(amplitudes.size()); + for (auto i = 0; i < amplitudes.size(); i++) { + this->wfmParam.amplitudes[i] = amplitudes[i]; + } } -Eigen::VectorXd ArrayWaveform::ArrayParam::getAmplitude() { - return this->amplitudes; +std::vector<double> ArrayWaveform::getAmplitude() { + std::vector<double> v( + this->wfmParam.amplitudes.data(), + this->wfmParam.amplitudes.data() + this->wfmParam.amplitudes.size() + ); + return v; } -void ArrayWaveform::ArrayParam::setDefaultParam() { - if (this->freqTones.size() == 0) {return;} - auto numTones = this->freqTones.size(); - this->setAmplitude(Eigen::VectorXd::Ones(numTones) * std::pow(2, 12)); - this->setPhase(Eigen::VectorXd::Zero(numTones)); - this->samplingRate = 614.4e6; - this->freqResolution = 1e3; +void ArrayWaveform::setDefaultParam() { + if (this->wfmParam.freqTones.size() == 0) {return;} + auto numTones = this->wfmParam.freqTones.size(); + this->setAmplitude(std::vector(numTones, 4096.0)); + this->setPhase(std::vector(numTones, 0.0)); + this->wfmParam.samplingRate = 614.4e6; + this->wfmParam.freqResolution = 1e3; } -void ArrayWaveform::ArrayParam::saveParam(std::string fileName) { +void ArrayWaveform::saveParam(std::string fileName) { const static Eigen::IOFormat csvFormat( Eigen::FullPrecision, Eigen::DontAlignCols, @@ -90,72 +107,99 @@ void ArrayWaveform::ArrayParam::saveParam(std::string fileName) { ); std::ofstream saveFile(fileName); if (saveFile.is_open()) { - saveFile << "samplingRate," << this->samplingRate << "\n"; - saveFile << "freqResolution," << this->freqResolution << "\n"; + saveFile << "samplingRate," << this->wfmParam.samplingRate << "\n"; + saveFile << "freqResolution," << this->wfmParam.freqResolution << "\n"; saveFile << "freqTones," - << this->freqTones.format(csvFormat) + << this->wfmParam.freqTones.format(csvFormat) << "\n"; saveFile << "phases," - << this->phases.format(csvFormat) + << this->wfmParam.phases.format(csvFormat) << "\n"; saveFile << "amplitudes," - << this->amplitudes.format(csvFormat) + << this->wfmParam.amplitudes.format(csvFormat) << "\n"; saveFile.close(); } } -void ArrayWaveform::ArrayParam::loadParam(std::string fileName) { +void ArrayWaveform::loadParam(std::string fileName) { std::ifstream file(fileName); + if (!file.is_open()) { + std::cout << fileName + << " does not exists in loadParam()" + << std::endl; + return; + } int lineCounter = 0; for (auto& line : CSVRange(file)) { std::vector<int> lineDataI; std::vector<double> lineDataD; switch (lineCounter) { case 0: - this->samplingRate = std::stoi(std::string(line[1])); + this->wfmParam.samplingRate = std::stoi(std::string(line[0])); break; case 1: - this->freqResolution = std::stoi(std::string(line[1])); + this->wfmParam.freqResolution = std::stoi(std::string(line[0])); break; case 2: - for (auto i = 1; i < line.size(); i++) { + for (auto i = 0; i < line.size() - 1; i++) { lineDataI.push_back(std::stoi(std::string(line[i]))); } - this->freqTones.resize(lineDataI.size()); - this->freqTones(lineDataI.data()); + setFreqTone(lineDataI); break; case 3: - for (auto i = 1; i < line.size(); i++) { + for (auto i = 0; i < line.size() - 1; i++) { lineDataD.push_back(std::stod(std::string(line[i]))); } - this->phases.resize(lineDataD.size()); - this->phases(lineDataD.data()); + setPhase(lineDataD); break; case 4: - for (auto i = 1; i < line.size(); i++) { + for (auto i = 0; i < line.size() - 1; i++) { lineDataD.push_back(std::stod(std::string(line[i]))); } - this->amplitudes.resize(lineDataD.size()); - this->amplitudes(lineDataD.data()); + setAmplitude(lineDataD); break; } lineCounter++; } } -void ArrayWaveform::ArrayParam::printParam() { - std::cout << "sampling rate: " << this->samplingRate << "\n"; - std::cout << "frequency resolution: " << this->freqResolution << "\n\n"; - std::cout << "frequency tones (MHz): " << "\n" << this->freqTones.array() / int(1e6) << "\n\n"; - std::cout << "phases:" << "\n" << this->phases << "\n\n"; - std::cout << "amplitudes:" << "\n" << this->amplitudes << "\n"; +void ArrayWaveform::printParam() { + std::cout << "sampling rate: " << this->wfmParam.samplingRate << "\n"; + std::cout << "frequency resolution: " << this->wfmParam.freqResolution << "\n\n"; + std::cout << "frequency tones (MHz): " << "\n" << this->wfmParam.freqTones.array() / int(1e6) << "\n\n"; + std::cout << "phases:" << "\n" << this->wfmParam.phases << "\n\n"; + std::cout << "amplitudes:" << "\n" << this->wfmParam.amplitudes << "\n\n"; } -ulong ArrayWaveform::getMinSampleLen( - ulong samplingRate, - ulong freqResolution -) { +void ArrayWaveform::bindBuffer(int64_t bytes) { + this->unbindBuffer(); + int fd = open("/dev/zero", O_RDONLY); + this->pDataBuffer = mmap( + NULL, + bytes, + PROT_READ | PROT_WRITE, + MAP_PRIVATE, + fd, + 0 + ); + if (this->pDataBuffer != MAP_FAILED) { + memset(this->pDataBuffer, 0, bytes); + this->dataLen = bytes / 2; + int16_t* pData = (int16_t*) this->pDataBuffer; + } + close(fd); +} + +void ArrayWaveform::unbindBuffer() { + if (this->dataLen != 0 and this->pDataBuffer != nullptr) { + munmap(this->pDataBuffer, this->dataLen); + this->pDataBuffer = nullptr; + this->dataLen = 0; + } +} + +ulong ArrayWaveform::getMinSampleLen(ulong samplingRate, ulong freqResolution) { return 2 * samplingRate / std::gcd(samplingRate, freqResolution); } @@ -215,23 +259,31 @@ double ArrayWaveform::setMovingSegment( return nextPhase; } -EigenVectorXi16 ArrayWaveform::getStaticWaveform(const ArrayParam& param) { - auto minSampleLen = 2 * param.samplingRate - / std::gcd(param.samplingRate, param.freqResolution); +std::pair<int16_t*, int64_t> ArrayWaveform::getStaticWaveform() { + auto minSampleLen = 2 * this->wfmParam.samplingRate + / std::gcd( + this->wfmParam.samplingRate, + this->wfmParam.freqResolution + ); Eigen::VectorXd t = Eigen::VectorXd::LinSpaced( minSampleLen, 0, minSampleLen - 1 - ) / param.samplingRate; - Eigen::MatrixXd wfmMatrix = Eigen::sin( - ((param.freqTones * t.transpose() * M_PI * 2).array().colwise() - + param.phases.array()) - ).array().colwise() * param.amplitudes.array(); - return wfmMatrix.colwise().sum().cast<int16_t>(); + ) / this->wfmParam.samplingRate; + Eigen::MatrixXd wfmMatrixrix = Eigen::sin( + ( + (this->wfmParam.freqTones * t.transpose() * M_PI * 2) + .array().colwise() + + this->wfmParam.phases.array()) + ).array().colwise() * this->wfmParam.amplitudes.array(); + bindBuffer(minSampleLen * 2); // bytes + auto pData = (int16_t*) this->pDataBuffer; + Eigen::Map<EigenVectorXi16> dataMap(pData, minSampleLen); + dataMap = wfmMatrixrix.colwise().sum().cast<int16_t>(); + return std::pair(pData, int64_t(minSampleLen)); } -EigenVectorXi16 ArrayWaveform::getTrickWaveform( - const ArrayParam& param, +std::pair<int16_t*, int64_t> ArrayWaveform::getTrickWaveform( std::set<int> siteIndex, double df, double tauMove, @@ -239,7 +291,7 @@ EigenVectorXi16 ArrayWaveform::getTrickWaveform( ) { if ((tauMove == 0 and tauStay == 0) or siteIndex.empty()) { - return getStaticWaveform(param); + return getStaticWaveform(); } if (tauMove != 0 and tauStay != 0) { tauStay = std::ceil((tauMove + tauStay) * df) / df - tauMove; @@ -249,21 +301,25 @@ EigenVectorXi16 ArrayWaveform::getTrickWaveform( tauStay = std::ceil(tauStay * df) / df; } auto tauTotal = tauMove * 2 + tauStay; - ulong sampleLen = getSampleLen(tauTotal, param.samplingRate, param.freqResolution); - ulong moveLen = tauMove * param.samplingRate; - ulong stayLen = tauStay * param.samplingRate; + ulong sampleLen = getSampleLen( + tauTotal, + this->wfmParam.samplingRate, + this->wfmParam.freqResolution + ); + ulong moveLen = tauMove * this->wfmParam.samplingRate; + ulong stayLen = tauStay * this->wfmParam.samplingRate; auto idxSeg0 = moveLen; auto idxSeg1 = moveLen + stayLen; auto idxSeg2 = moveLen + stayLen + moveLen; - auto t = Eigen::ArrayXd::LinSpaced(sampleLen, 0, sampleLen - 1) / param.samplingRate; - Eigen::MatrixXd wfmMat(sampleLen, param.freqTones.size()); // site wfm stored column by column - for (auto i = 0; i < param.freqTones.size(); i++) { - wfmMat.col(i) = t; - Eigen::Ref<Eigen::ArrayXd> siteWfm = wfmMat.col(i); - auto fInit = param.freqTones[i]; + auto t = Eigen::ArrayXd::LinSpaced(sampleLen, 0, sampleLen - 1) / this->wfmParam.samplingRate; + Eigen::MatrixXd wfmMatrix(sampleLen, this->wfmParam.freqTones.size()); // site wfm stored column by column + for (auto i = 0; i < this->wfmParam.freqTones.size(); i++) { + wfmMatrix.col(i) = t; + Eigen::Ref<Eigen::ArrayXd> siteWfm = wfmMatrix.col(i); + auto fInit = this->wfmParam.freqTones[i]; auto fFinal = fInit + df; - auto phi = param.phases[i]; - auto amp = param.amplitudes[i]; + auto phi = this->wfmParam.phases[i]; + auto amp = this->wfmParam.amplitudes[i]; if (siteIndex.contains(i)) { if (tauMove != 0) { phi = setMovingSegment( @@ -291,10 +347,14 @@ EigenVectorXi16 ArrayWaveform::getTrickWaveform( setStaticSegment(siteWfm, fInit, phi, amp); } } - return wfmMat.rowwise().sum().cast<int16_t> (); + bindBuffer(sampleLen * 2); + auto pData = (int16_t*) this->pDataBuffer; + Eigen::Map<EigenVectorXi16> dataMap(pData, sampleLen); + dataMap = wfmMatrix.rowwise().sum().cast<int16_t> (); + return std::pair(pData, int64_t(sampleLen)); } -void ArrayWaveform::saveCSV(std::string fileName, EigenVectorXi16 wfm) { +void ArrayWaveform::saveWaveform(std::string fileName) { const static Eigen::IOFormat csvFormat( Eigen::FullPrecision, Eigen::DontAlignCols, @@ -302,6 +362,8 @@ void ArrayWaveform::saveCSV(std::string fileName, EigenVectorXi16 wfm) { ",", "" ); + auto pData = (int16_t*) this->pDataBuffer; + auto wfm = Eigen::Map<EigenVectorXi16>(pData, this->dataLen); std::ofstream saveFile(fileName); if (saveFile.is_open()) { saveFile << wfm.format(csvFormat); diff --git a/Cpp/lib/waveform.h b/Cpp/lib/waveform.h index b923d3b..a46f682 100644 --- a/Cpp/lib/waveform.h +++ b/Cpp/lib/waveform.h @@ -1,48 +1,24 @@ #pragma once -#include <Eigen/Dense> +#include "external/Eigen/Dense" #include <string> #include <set> typedef Eigen::Vector<int16_t, Eigen::Dynamic> EigenVectorXi16; -namespace ArrayWaveform { - - class ArrayParam { - public: +class ArrayWaveform { + private: + void* pDataBuffer; + int64_t dataLen; + struct WaveformParam { unsigned long samplingRate; unsigned long freqResolution; Eigen::VectorXd freqTones; Eigen::VectorXd phases; Eigen::VectorXd amplitudes; - - ArrayParam(); - ArrayParam(const ArrayParam& other); - - void setSamplingRate(unsigned long sr); - void setFreqResolution(unsigned long fr); - - void setFreqTone( - int centerFreq, - int freqSpacing, - int numTones - ); - void setFreqTone(const Eigen::VectorXd& tones); - Eigen::VectorXd getFreqTone(); - void setPhase(const Eigen::VectorXd& phases); - Eigen::VectorXd getPhase(); - void setAmplitude(const Eigen::VectorXd& amplitudes); - Eigen::VectorXd getAmplitude(); - void setDefaultParam(); - void saveParam(std::string fileName); - void loadParam(std::string fileName); - void printParam(); }; + WaveformParam wfmParam; - ulong getMinSampleLen(ulong samplingRate, ulong freqResolution); - ulong getSampleLen( - double tau, - ulong samplingRate, - ulong freqResolution - ); + void bindBuffer(int64_t bytes); + void unbindBuffer(); double setStaticSegment( Eigen::Ref<Eigen::VectorXd> timeSeries, @@ -57,18 +33,51 @@ namespace ArrayWaveform { double initPhase, double amp ); + + public: + ArrayWaveform(); + ~ArrayWaveform(); - EigenVectorXi16 getStaticWaveform(const ArrayParam& param); - EigenVectorXi16 getTrickWaveform( - const ArrayParam& param, + void* getDataBuffer(); + int64_t getDataLen(); + + void setSamplingRate(ulong sr); + ulong getSamplingRate(); + void setFreqResolution(ulong fr); + ulong getFreqResolution(); + + void setFreqTone( + int centerFreq, + int freqSpacing, + int numTones + ); + void setFreqTone(const std::vector<int>& tones); + std::vector<double> getFreqTone(); + void setPhase(const std::vector<double>& phases); + std::vector<double> getPhase(); + void setAmplitude(const std::vector<double>& amplitudes); + std::vector<double> getAmplitude(); + void setDefaultParam(); // optional helper + void saveParam(std::string fileName); // optional helper + void loadParam(std::string fileName); // optional helper + void printParam(); // optional helper + + ulong getMinSampleLen(ulong samplingRate, ulong freqResolution); + ulong getSampleLen( + double tau, + ulong samplingRate, + ulong freqResolution + ); + std::pair<int16_t*, int64_t> getStaticWaveform(); + std::pair<int16_t*, int64_t> getTrickWaveform( std::set<int> siteIndex, double df, double tauMove=0, double tauStay=0 ); - void saveCSV(std::string fileName, EigenVectorXi16 wfm); + void saveWaveform(std::string fileName); // optional helper; }; -namespace ArbitraryWaveform {}; +class ArbitraryWaveform {}; -- GitLab