commit dev-sun.

This commit is contained in:
sunwen
2023-12-22 11:17:18 +08:00
parent d015b38845
commit 410d657fe7
27 changed files with 1346 additions and 267 deletions

View File

@@ -4,7 +4,7 @@ project(UR)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_definitions(-DUSE_CUDA)
set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc) set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)
enable_language(CUDA) enable_language(CUDA)
find_package(CUDAToolkit REQUIRED) find_package(CUDAToolkit REQUIRED)
@@ -20,8 +20,9 @@ file(GLOB_RECURSE cpp_files ./src/*.cpp)
file(GLOB_RECURSE cu_files ./src/*.cu) file(GLOB_RECURSE cu_files ./src/*.cu)
file(GLOB_RECURSE cxx_files ./src/*.cxx) file(GLOB_RECURSE cxx_files ./src/*.cxx)
file(GLOB_RECURSE header_files ./src/*.h) file(GLOB_RECURSE header_files ./src/*.h)
add_executable(UR ${cpp_files} ${cxx_files} ${header_files} ${Aurora_Source}) add_executable(UR ${cpp_files} ${cu_files} ${cxx_files} ${header_files} ${Aurora_Source} ${Aurora_Source_Cu} ./src/Aurora.cu ${Aurora_DIR}/src/CudaMatrixPrivate.cu)
target_compile_options(UR PUBLIC ${Aurora_Complie_Options} "-march=native")
#target_compile_options(UR PUBLIC ${Aurora_Complie_Options} "-march=native")
target_include_directories(UR PUBLIC ./src/) target_include_directories(UR PUBLIC ./src/)
target_include_directories(UR PUBLIC ${Aurora_INCLUDE_DIRS}) target_include_directories(UR PUBLIC ${Aurora_INCLUDE_DIRS})
target_include_directories(UR PUBLIC ${DCMTK_INCLUDE_DIRS}) target_include_directories(UR PUBLIC ${DCMTK_INCLUDE_DIRS})
@@ -51,8 +52,9 @@ set_target_properties(UR PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
#                        -arch sm_75 #                        -arch sm_75
#                        >) #                        >)
target_compile_options(UR PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: target_compile_options(UR PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:
-arch=sm_75 -arch=sm_75 --expt-extended-lambda
>) >)
target_link_libraries(UR PRIVATE ${CUDA_RUNTIME_LIBRARY} CUDA::cufft CUDA::cudart) target_link_libraries(UR PRIVATE ${CUDA_RUNTIME_LIBRARY} CUDA::cufft CUDA::cudart)
# target_link_libraries(UR PUBLIC URDepends::SaftATT) # target_link_libraries(UR PUBLIC URDepends::SaftATT)

201
src/Aurora.cu Normal file
View File

@@ -0,0 +1,201 @@
#include "/usr/local/cuda-10.1/targets/x86_64-linux/include/cufft.h"
#include </usr/local/cuda-10.1/targets/x86_64-linux/include/cuda_runtime.h>
#include <cstdio>
#include <thrust/device_vector.h>
#include <thrust/execution_policy.h>
#include <thrust/sort.h>
#include "Aurora.h"
#include "AuroraDefs.h"
#include "CudaMatrix.h"
#include <iostream>
#include "log/log.h"
#include <cuda_texture_types.h>
__global__ void doubleToComplexKernel(const double* input, cufftDoubleComplex* output, int size)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < size) {
output[idx].x = input[idx];
output[idx].y = 0;
}
}
void Aurora::doubleToComplex(const double* input, cufftDoubleComplex* output, int size)
{
int threadsPerBlock = 1024;
int blocksPerGrid = (size + threadsPerBlock - 1) / threadsPerBlock;
doubleToComplexKernel<<<blocksPerGrid, threadsPerBlock>>>(input, output, size);
cudaDeviceSynchronize(); // 等待GPU完成操作
}
__global__ void maxKernel(const float* aInput, const float* aOutput, int aSize)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = gridDim.x*blockDim.x;
float maxResult = aInput[0];
while (index < aSize)
{
if(maxResult < aInput[index])
{
maxResult = aInput[index];
}
index += stride;
}
}
void Aurora::max(const float* aInput, const float* aOutput, int aSize)
{
int threadsPerBlock = 1024;
int blocksPerGrid = 68;
//max<<<blocksPerGrid, threadsPerBlock>>>(aInput, aOutput, aSize);
cudaDeviceSynchronize();
}
__global__ void validKernel(const float* aData, const float* aValid, float* aOutput, int aOutputRowCount, int aOutputColumnCount)
{
int threadIndex = blockIdx.x * blockDim.x + threadIdx.x;
int dataIndex = (int)aValid[threadIndex];
if(threadIndex < aOutputColumnCount)
{
for(int i=0; i < aOutputRowCount; ++i)
{
aOutput[threadIndex * aOutputRowCount + i] = aData[dataIndex * aOutputRowCount + i];
}
}
}
// __global__ void validSubKernel(const double* aValid, double* aOutput, unsigned int* aCount, int aValidSize)
// {
// int index = blockIdx.x * blockDim.x + threadIdx.x;
// if(index == 0)
// {
// for(int i=0;i<aValidSize;++i)
// {
// if(aValid[i] == 1)
// {
// aOutput[*aCount] = i;
// ++(*aCount);
// }
// }
// }
// __syncthreads();
// }
Aurora::CudaMatrix Aurora::valid(const Aurora::CudaMatrix aData, const Aurora::CudaMatrix aValid)
{
int validSize = aValid.getDataSize();
int rowCount = aData.getDimSize(0);
float* hostValid = new float[validSize];
float* validProcessed = new float[validSize];
float* validProcessedDevice = nullptr;
cudaMemcpy(hostValid, aValid.getData(), sizeof(float) * validSize, cudaMemcpyDeviceToHost);
int validColumnCount = 0;
for(int i=0;i<validSize;++i)
{
if(hostValid[i] == 1)
{
validProcessed[validColumnCount] = i;
++validColumnCount;
}
}
cudaMalloc((void**)&validProcessedDevice, sizeof(float) * validColumnCount );
cudaMemcpy(validProcessedDevice, validProcessed, sizeof(float) * validColumnCount, cudaMemcpyHostToDevice);
int threadPerBlock = 1024;
int blockPerGrid = validColumnCount / threadPerBlock + 1;
float* result = nullptr;
cudaMalloc((void**)&result, sizeof(float) * validColumnCount * rowCount);
validKernel<<<blockPerGrid, threadPerBlock>>>(aData.getData(), validProcessedDevice, result, rowCount, validColumnCount);
cudaDeviceSynchronize();
cudaFree(validProcessedDevice);
delete[] hostValid;
delete[] validProcessed;
return Aurora::CudaMatrix::fromRawData(result, rowCount, validColumnCount);
}
texture<float, cudaTextureType2D, cudaReadModeElementType> tex;
cudaArray* array;
__global__ void testKernel(float* aData,cudaTextureObject_t aTexObj, cudaSurfaceObject_t aSurface)
{
float a = tex2D(tex,5.5,5.5);
float b = tex2D<float>(aTexObj,5.5,5.5);
float2 c = tex2D<float2>(aSurface,1,1);
printf("%f\n",a);
printf("%f\n",b);
printf("%f\n",c.x);
printf("%f\n",c.y);
}
__global__ void writeSurfaceKernel( cudaSurfaceObject_t aSurface)
{
float2 value;
value.x = 100;
value.y = 99;
surf2Dwrite(value, aSurface, 1, 1 );
}
void subTest(cudaTextureObject_t& aTexture)
{
cudaResourceDesc resourceDesc;
cudaTextureDesc textureDesc;
memset(&resourceDesc, 0, sizeof(resourceDesc));
resourceDesc.resType = cudaResourceTypeArray;
resourceDesc.res.array.array = array; // 指向设备端的 CUDA 数组
// 在 textureDesc 中设置纹理描述
memset(&textureDesc, 0, sizeof(textureDesc));
textureDesc.addressMode[0] = cudaAddressModeClamp;
textureDesc.addressMode[1] = cudaAddressModeClamp;
textureDesc.filterMode = cudaFilterModeLinear;
textureDesc.readMode = cudaReadModeElementType;
textureDesc.normalizedCoords = false;
//textureDesc.channelDesc = texChannelDescSpeedOfSoundField;
cudaCreateTextureObject(&aTexture, &resourceDesc, &textureDesc, nullptr);
}
void Aurora::test(float* aData)
{
tex.addressMode[0] = cudaAddressModeClamp; // Texturreferenz beschreiben
tex.addressMode[1] = cudaAddressModeClamp;
tex.filterMode = cudaFilterModeLinear;
tex.normalized = 0;
cudaChannelFormatDesc texChannelDescSpeedOfSoundField = cudaCreateChannelDesc(32, 0, 0, 0, cudaChannelFormatKindFloat);
cudaMallocArray(&array, &texChannelDescSpeedOfSoundField, 10, 9);
cudaMemcpyToArray(array, 0, 0, aData,10 * 9 *sizeof(float), cudaMemcpyHostToDevice);
cudaBindTextureToArray ( &tex, array, &texChannelDescSpeedOfSoundField );
cudaTextureObject_t textureObj;
subTest(textureObj);
struct cudaResourceDesc resDesc;
memset(&resDesc, 0, sizeof(resDesc));
resDesc.resType = cudaResourceTypeArray;
// Create the surface objects
resDesc.res.array.array = array;
cudaSurfaceObject_t inputSurfObj = 0;
cudaCreateSurfaceObject(&inputSurfObj, &resDesc);
writeSurfaceKernel<<<1,1>>>(inputSurfObj);
cudaDeviceSynchronize();
testKernel<<<1, 1>>>(aData,textureObj, inputSurfObj);
cudaDeviceSynchronize();
cudaUnbindTexture(&tex);
}
void Aurora::sort(const Aurora::Matrix& aMatrix)
{
RECON_INFO("cuda start");
thrust::sort(thrust::device, aMatrix.getData(), aMatrix.getData()+aMatrix.getDataSize(), thrust::greater<int>());
RECON_INFO("cuda end");
}

24
src/Aurora.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef SUM_MATRIX_CU_H
#define SUM_MATRIX_CU_H
#include "/usr/local/cuda-10.1/targets/x86_64-linux/include/cufft.h"
#include </usr/local/cuda-10.1/targets/x86_64-linux/include/cuda_runtime.h>
#include "Matrix.h"
namespace Aurora
{
//__global__ void doubleToComplexKernel(const double* input, cufftDoubleComplex* output, int size);
void doubleToComplex(const double* input, cufftDoubleComplex* output, int size);
//__global__ void maxKernel(const float* aInput, const float* aOutput, int aSize);
void max(const float* aInput, const float* aOutput, int aSize);
Aurora::CudaMatrix valid(const Aurora::CudaMatrix aData, const Aurora::CudaMatrix aValid);
void test(float* aData);
void sort(const Aurora::Matrix& aMatrix);
//Aurora::CudaMatrix getTransmissionDataSubFunction(const Aurora::CudaMatrix& aFxMatrix, const Aurora::CudaMatrix& aFhMatrix);
}
#endif

View File

@@ -5,98 +5,103 @@
#include <immintrin.h> #include <immintrin.h>
#include <sys/types.h> #include <sys/types.h>
namespace { namespace {
const ushort CONVERT_AND_VALUE = 15;
// andblack
const __m128i andBlock = _mm_set_epi16(15, 15, 15, 15, 15, 15, 15, 15);
const __m128i andBlock2 =
_mm_set_epi16(2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047);
const __m128i zeroBlock = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, 0);
const __m128i oneBlock = _mm_set_epi16(1, 1, 1, 1, 1, 1, 1, 1);
const __m128i twokBlock =
_mm_set_epi16(2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048);
const uint CONVERT_ADD_VALUE = UINT32_MAX - 4095;
void convert(short * ptr, float* des,bool single = false){
// 初始化值
auto value = _mm_set_epi16(ptr[0], ptr[1], ptr[2], ptr[3], single?ptr[0]:ptr[4], single?ptr[0]:ptr[5],
single?ptr[0]:ptr[6], single?ptr[0]:ptr[7]);
auto uvalue = _mm_set_epi16(
(ushort)ptr[0], (ushort)ptr[1], (ushort)ptr[2], (ushort)ptr[3],
(ushort)(single?ptr[0]:ptr[4]), (ushort)(single?ptr[0]:ptr[5]),
(ushort)(single?ptr[0]:ptr[6]), (ushort)(single?ptr[0]:ptr[7]));
// 位移
auto sign_bit = _mm_srli_epi16(value, 15); // 右移16位取符号位
auto exponent = _mm_srli_epi16(uvalue, 11);
// and
exponent = _mm_and_si128(exponent, andBlock);
// and then convert to int 32 bits
auto fraction3 = _mm256_cvtepi16_epi32(_mm_and_si128(uvalue, andBlock2));
auto hidden_bit_mask =
(_mm_cmp_epi16_mask(sign_bit, oneBlock, _MM_CMPINT_EQ) &
_mm_cmp_epi16_mask(exponent, zeroBlock, _MM_CMPINT_EQ)) |
(_mm_cmp_epi16_mask(sign_bit, zeroBlock, _MM_CMPINT_EQ) &
_mm_cmp_epi16_mask(exponent, zeroBlock, _MM_CMPINT_NE));
auto hidden_bit16 = _mm_maskz_set1_epi16(hidden_bit_mask, 2048);
auto hidden_bit32 = _mm256_cvtepi16_epi32(hidden_bit16);
auto outputBlock = _mm256_add_epi32(fraction3, hidden_bit32);
auto sign_bit_add_value = _mm256_maskz_set1_epi32(
_mm_cmp_epi16_mask(sign_bit, oneBlock, _MM_CMPINT_EQ),
CONVERT_ADD_VALUE);
outputBlock = _mm256_add_epi32(outputBlock, sign_bit_add_value);
auto exponent_mask =
_mm_cmp_epi16_mask(oneBlock, exponent, _MM_CMPINT_LT);
exponent = _mm_sub_epi16(exponent, oneBlock);
auto exponent32 = _mm256_cvtepi16_epi32(exponent);
auto zeroBlock32 = _mm256_cvtepi16_epi32(zeroBlock);
auto offsetCount =
_mm256_mask_blend_epi32(exponent_mask, zeroBlock32, exponent32);
outputBlock = _mm256_sllv_epi32(outputBlock, offsetCount); // const ushort CONVERT_AND_VALUE = 15;
// // andblack
// const __m128i andBlock = _mm_set_epi16(15, 15, 15, 15, 15, 15, 15, 15);
// const __m128i andBlock2 =
// _mm_set_epi16(2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047);
// const __m128i zeroBlock = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, 0);
// const __m128i oneBlock = _mm_set_epi16(1, 1, 1, 1, 1, 1, 1, 1);
// const __m128i twokBlock =
// _mm_set_epi16(2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048);
// const uint CONVERT_ADD_VALUE = UINT32_MAX - 4095;
// void convert(short * ptr, double* des,bool single = false){
// // 初始化值
// auto value = _mm_set_epi16(ptr[0], ptr[1], ptr[2], ptr[3], single?ptr[0]:ptr[4], single?ptr[0]:ptr[5],
// single?ptr[0]:ptr[6], single?ptr[0]:ptr[7]);
// auto uvalue = _mm_set_epi16(
// (ushort)ptr[0], (ushort)ptr[1], (ushort)ptr[2], (ushort)ptr[3],
// (ushort)(single?ptr[0]:ptr[4]), (ushort)(single?ptr[0]:ptr[5]),
// (ushort)(single?ptr[0]:ptr[6]), (ushort)(single?ptr[0]:ptr[7]));
// // 位移
// auto sign_bit = _mm_srli_epi16(value, 15); // 右移16位取符号位
// auto exponent = _mm_srli_epi16(uvalue, 11);
// // and
// exponent = _mm_and_si128(exponent, andBlock);
// // and then convert to int 32 bits
// auto fraction3 = _mm256_cvtepi16_epi32(_mm_and_si128(uvalue, andBlock2));
// auto hidden_bit_mask =
// (_mm_cmp_epi16_mask(sign_bit, oneBlock, _MM_CMPINT_EQ) &
// _mm_cmp_epi16_mask(exponent, zeroBlock, _MM_CMPINT_EQ)) |
// (_mm_cmp_epi16_mask(sign_bit, zeroBlock, _MM_CMPINT_EQ) &
// _mm_cmp_epi16_mask(exponent, zeroBlock, _MM_CMPINT_NE));
// auto hidden_bit16 = _mm_maskz_set1_epi16(hidden_bit_mask, 2048);
// auto hidden_bit32 = _mm256_cvtepi16_epi32(hidden_bit16);
// auto outputBlock = _mm256_add_epi32(fraction3, hidden_bit32);
// auto sign_bit_add_value = _mm256_maskz_set1_epi32(
// _mm_cmp_epi16_mask(sign_bit, oneBlock, _MM_CMPINT_EQ),
// CONVERT_ADD_VALUE);
// outputBlock = _mm256_add_epi32(outputBlock, sign_bit_add_value);
// auto exponent_mask =
// _mm_cmp_epi16_mask(oneBlock, exponent, _MM_CMPINT_LT);
// exponent = _mm_sub_epi16(exponent, oneBlock);
// auto exponent32 = _mm256_cvtepi16_epi32(exponent);
// auto zeroBlock32 = _mm256_cvtepi16_epi32(zeroBlock);
// auto offsetCount =
// _mm256_mask_blend_epi32(exponent_mask, zeroBlock32, exponent32);
// outputBlock = _mm256_sllv_epi32(outputBlock, offsetCount);
des[3] = _mm256_extract_epi32(outputBlock, 4); // des[3] = _mm256_extract_epi32(outputBlock, 4);
des[2] = _mm256_extract_epi32(outputBlock, 5); // des[2] = _mm256_extract_epi32(outputBlock, 5);
des[1] = _mm256_extract_epi32(outputBlock, 6); // des[1] = _mm256_extract_epi32(outputBlock, 6);
des[0] = _mm256_extract_epi32(outputBlock, 7); // des[0] = _mm256_extract_epi32(outputBlock, 7);
if(single) return; // if(single) return;
des[7] = _mm256_extract_epi32(outputBlock, 0); // des[7] = _mm256_extract_epi32(outputBlock, 0);
des[6] = _mm256_extract_epi32(outputBlock, 1); // des[6] = _mm256_extract_epi32(outputBlock, 1);
des[5] = _mm256_extract_epi32(outputBlock, 2); // des[5] = _mm256_extract_epi32(outputBlock, 2);
des[4] = _mm256_extract_epi32(outputBlock, 3); // des[4] = _mm256_extract_epi32(outputBlock, 3);
} // }
} }
Aurora::Matrix Recon::convertfp16tofloat(Aurora::Matrix aMatrix) { Aurora::Matrix Recon::convertfp16tofloat(Aurora::Matrix aMatrix) {
auto input = aMatrix.getData();
// uint16变换为float(32位)输出大小翻倍
auto output = Aurora::malloc(aMatrix.getDataSize() * 4);
size_t rows = aMatrix.getDataSize() * sizeof(float) / sizeof(short);
size_t total_count = aMatrix.getDataSize();
#pragma omp parallel for // auto input = aMatrix.getData();
for (size_t i = 0; i < total_count; i += 8) { // // uint16变换为float(32位)输出大小翻倍
// 循环展开以避免过度的线程调用 // auto output = Aurora::malloc(aMatrix.getDataSize() * 4);
if (i < total_count) { // size_t rows = aMatrix.getDataSize() * sizeof(double) / sizeof(short);
auto ptr = (short *)(input + i); // size_t total_count = aMatrix.getDataSize();
float *des = output + i * 4;
::convert(ptr, des,i+1>total_count);
} // #pragma omp parallel for
if (i+2 < total_count) { // for (size_t i = 0; i < total_count; i += 8) {
auto ptr = (short *)(input + i + 2); // // 循环展开以避免过度的线程调用
float *des = output + (i+2) * 4; // if (i < total_count) {
::convert(ptr, des,i+3>total_count); // auto ptr = (short *)(input + i);
} // double *des = output + i * 4;
if (i+4 < total_count) { // ::convert(ptr, des,i+1>total_count);
auto ptr = (short *)(input + i + 4); // }
float *des = output + (i+4) * 4; // if (i+2 < total_count) {
::convert(ptr, des,i+5>total_count); // auto ptr = (short *)(input + i + 2);
} // double *des = output + (i+2) * 4;
if (i+6 < total_count) { // ::convert(ptr, des,i+3>total_count);
auto ptr = (short *)(input + i + 6); // }
float *des = output + (i+6) * 4; // if (i+4 < total_count) {
::convert(ptr, des,i+7>total_count); // auto ptr = (short *)(input + i + 4);
} // double *des = output + (i+4) * 4;
} // ::convert(ptr, des,i+5>total_count);
return Aurora::Matrix::New(output, aMatrix.getDimSize(0), // }
aMatrix.getDimSize(1), aMatrix.getDimSize(2)); // if (i+6 < total_count) {
// auto ptr = (short *)(input + i + 6);
// double *des = output + (i+6) * 4;
// ::convert(ptr, des,i+7>total_count);
// }
// }
// return Aurora::Matrix::New(output, aMatrix.getDimSize(0),
// aMatrix.getDimSize(1), aMatrix.getDimSize(2));
} }

View File

@@ -1,5 +1,6 @@
#include "getAScanBlockPreprocessed.h" #include "getAScanBlockPreprocessed.h"
#include "CudaMatrix.h"
#include "Matrix.h" #include "Matrix.h"
#include "blockingGeometryInfo.h" #include "blockingGeometryInfo.h"
#include "removeDataFromArrays.h" #include "removeDataFromArrays.h"
@@ -10,15 +11,36 @@
#include "src/transmissionReconstruction/dataFilter/dataFilter.h" #include "src/transmissionReconstruction/dataFilter/dataFilter.h"
#include "src/reflectionReconstruction/dataFilter.h" #include "src/reflectionReconstruction/dataFilter.h"
#include "Aurora.h"
using namespace Aurora; using namespace Aurora;
using namespace Recon; using namespace Recon;
#include <sys/time.h>
#include <iostream>
void printTime()
{
struct timeval tpend;
gettimeofday(&tpend,NULL);
int secofday = (tpend.tv_sec + 3600 * 8 ) % 86400;
int hours = secofday / 3600;
int minutes = (secofday - hours * 3600 ) / 60;
int seconds = secofday % 60;
int milliseconds = tpend.tv_usec/1000;
std::cout<< hours << ":" <<minutes<<":"<<seconds<<"."<<milliseconds<<std::endl;
}
AscanBlockPreprocessed Recon::getAscanBlockPreprocessed(Parser* aParser, const Aurora::Matrix& aMp, const Aurora::Matrix& aSl, const Aurora::Matrix& aSn, AscanBlockPreprocessed Recon::getAscanBlockPreprocessed(Parser* aParser, const Aurora::Matrix& aMp, const Aurora::Matrix& aSl, const Aurora::Matrix& aSn,
const Aurora::Matrix& aRl, const Aurora::Matrix& aRn, GeometryInfo& aGeom, const MeasurementInfo& aMeasInfo, const Aurora::Matrix& aRl, const Aurora::Matrix& aRn, GeometryInfo& aGeom, const MeasurementInfo& aMeasInfo,
bool aApplyFilter, bool aTransReco) bool aApplyFilter, bool aTransReco)
{ {
//std::cout<<"strart"<<std::endl;
//printTime();
//550ms
AscanBlockPreprocessed result; AscanBlockPreprocessed result;
AscanBlock ascanBlock = getAscanBlock(aParser, aMp, aSl, aSn, aRl, aRn); AscanBlock ascanBlock = getAscanBlock(aParser, aMp, aSl, aSn, aRl, aRn);
//printTime();
//10ms
result.gainBlock = ascanBlock.gainBlock; result.gainBlock = ascanBlock.gainBlock;
result.mpBlock = ascanBlock.mpBlock; result.mpBlock = ascanBlock.mpBlock;
result.rlBlock = ascanBlock.rlBlock; result.rlBlock = ascanBlock.rlBlock;
@@ -26,6 +48,8 @@ AscanBlockPreprocessed Recon::getAscanBlockPreprocessed(Parser* aParser, const A
result.slBlock = ascanBlock.slBlock; result.slBlock = ascanBlock.slBlock;
result.snBlock = ascanBlock.snBlock; result.snBlock = ascanBlock.snBlock;
GeometryBlock geometryBlock = blockingGeometryInfos(aGeom, ascanBlock.rnBlock, ascanBlock.rlBlock, ascanBlock.snBlock, ascanBlock.slBlock, ascanBlock.mpBlock); GeometryBlock geometryBlock = blockingGeometryInfos(aGeom, ascanBlock.rnBlock, ascanBlock.rlBlock, ascanBlock.snBlock, ascanBlock.slBlock, ascanBlock.mpBlock);
//printTime();
//3ms
result.receiverPositionBlock = geometryBlock.receiverPositionBlock; result.receiverPositionBlock = geometryBlock.receiverPositionBlock;
result.senderPositionBlock = geometryBlock.senderPositionBlock; result.senderPositionBlock = geometryBlock.senderPositionBlock;
if(aApplyFilter) if(aApplyFilter)
@@ -40,7 +64,8 @@ AscanBlockPreprocessed Recon::getAscanBlockPreprocessed(Parser* aParser, const A
{ {
usedData = filterReflectionData(geometryBlock.receiverPositionBlock, geometryBlock.senderPositionBlock, geometryBlock.senderNormalBlock, reflectParams::constrictReflectionAngles); usedData = filterReflectionData(geometryBlock.receiverPositionBlock, geometryBlock.senderPositionBlock, geometryBlock.senderNormalBlock, reflectParams::constrictReflectionAngles);
} }
//printTime();
//150ms
ascanBlock.ascanBlock = removeDataFromArrays(ascanBlock.ascanBlock, usedData); ascanBlock.ascanBlock = removeDataFromArrays(ascanBlock.ascanBlock, usedData);
result.mpBlock = removeDataFromArrays(ascanBlock.mpBlock, usedData); result.mpBlock = removeDataFromArrays(ascanBlock.mpBlock, usedData);
result.slBlock = removeDataFromArrays(ascanBlock.slBlock, usedData); result.slBlock = removeDataFromArrays(ascanBlock.slBlock, usedData);
@@ -51,7 +76,8 @@ AscanBlockPreprocessed Recon::getAscanBlockPreprocessed(Parser* aParser, const A
result.senderPositionBlock = removeDataFromArrays(geometryBlock.senderPositionBlock, usedData); result.senderPositionBlock = removeDataFromArrays(geometryBlock.senderPositionBlock, usedData);
result.receiverPositionBlock = removeDataFromArrays(geometryBlock.receiverPositionBlock, usedData); result.receiverPositionBlock = removeDataFromArrays(geometryBlock.receiverPositionBlock, usedData);
result.gainBlock = removeDataFromArrays(ascanBlock.gainBlock, usedData); result.gainBlock = removeDataFromArrays(ascanBlock.gainBlock, usedData);
//printTime();
//120ms
} }
if (ascanBlock.ascanBlock.getDataSize() > 0) if (ascanBlock.ascanBlock.getDataSize() > 0)
@@ -62,6 +88,72 @@ AscanBlockPreprocessed Recon::getAscanBlockPreprocessed(Parser* aParser, const A
{ {
result.ascanBlockPreprocessed = ascanBlock.ascanBlock; result.ascanBlockPreprocessed = ascanBlock.ascanBlock;
} }
//printTime();
return result; return result;
} }
AscanBlockPreprocessedCuda Recon::getAscanBlockPreprocessedCuda(Parser* aParser, const Aurora::Matrix& aMp, const Aurora::Matrix& aSl, const Aurora::Matrix& aSn,
const Aurora::Matrix& aRl, const Aurora::Matrix& aRn, GeometryInfo& aGeom, const MeasurementInfo& aMeasInfo,
bool aApplyFilter, bool aTransReco)
{
//std::cout<<"strart"<<std::endl;
//printTime();
//550ms
AscanBlockPreprocessedCuda result;
AscanBlock ascanBlock = getAscanBlock(aParser, aMp, aSl, aSn, aRl, aRn);
//printTime();
//300ms
result.ascanBlockPreprocessed = ascanBlock.ascanBlock.toDeviceMatrix();
result.gainBlock = ascanBlock.gainBlock.toDeviceMatrix();
result.mpBlock = ascanBlock.mpBlock;
result.rlBlock = ascanBlock.rlBlock;
result.rnBlock = ascanBlock.rnBlock;
result.slBlock = ascanBlock.slBlock;
result.snBlock = ascanBlock.snBlock;
GeometryBlock geometryBlock = blockingGeometryInfos(aGeom, ascanBlock.rnBlock, ascanBlock.rlBlock, ascanBlock.snBlock, ascanBlock.slBlock, ascanBlock.mpBlock);
//printTime();
//3ms
result.receiverPositionBlock = geometryBlock.receiverPositionBlock;
result.senderPositionBlock = geometryBlock.senderPositionBlock;
if(aApplyFilter)
{
Matrix usedData;
if(aTransReco)
{
usedData = filterTransmissionData(ascanBlock.slBlock, ascanBlock.snBlock, ascanBlock.rlBlock, ascanBlock.rnBlock,
aGeom.sensData, geometryBlock.senderNormalBlock, geometryBlock.receiverNormalBlock);
}
else
{
usedData = filterReflectionData(geometryBlock.receiverPositionBlock, geometryBlock.senderPositionBlock, geometryBlock.senderNormalBlock, reflectParams::constrictReflectionAngles);
}
//printTime();
//40ms
CudaMatrix usedDataDevice = usedData.toDeviceMatrix();
result.ascanBlockPreprocessed = valid(result.ascanBlockPreprocessed, usedDataDevice);
result.mpBlock = removeDataFromArrays(ascanBlock.mpBlock, usedData);
result.slBlock = removeDataFromArrays(ascanBlock.slBlock, usedData);
result.snBlock = removeDataFromArrays(ascanBlock.snBlock, usedData);
result.rlBlock = removeDataFromArrays(ascanBlock.rlBlock, usedData);
result.rnBlock = removeDataFromArrays(ascanBlock.rnBlock, usedData);
result.senderPositionBlock = removeDataFromArrays(geometryBlock.senderPositionBlock, usedData);
result.receiverPositionBlock = removeDataFromArrays(geometryBlock.receiverPositionBlock, usedData);
result.gainBlock = valid(result.gainBlock, usedDataDevice);
//printTime();
//10ms
}
if (ascanBlock.ascanBlock.getDataSize() > 0)
{
result.ascanBlockPreprocessed = preprocessAscanBlockCuda(result.ascanBlockPreprocessed, aMeasInfo);
}
// else
// {
// result.ascanBlockPreprocessed = ascanBlock.ascanBlock;
// }
//printTime();
//std::cout<<"end"<<std::endl;
return result;
}

View File

@@ -2,6 +2,7 @@
#define GETASCANBLOCK_PREPROCESSED_H #define GETASCANBLOCK_PREPROCESSED_H
#include "Matrix.h" #include "Matrix.h"
#include "CudaMatrix.h"
#include "src/common/getGeometryInfo.h" #include "src/common/getGeometryInfo.h"
#include "src/common/getMeasurementMetaData.h" #include "src/common/getMeasurementMetaData.h"
@@ -25,6 +26,23 @@ namespace Recon
AscanBlockPreprocessed getAscanBlockPreprocessed(Parser* aParser, const Aurora::Matrix& aMp, const Aurora::Matrix& aSl, const Aurora::Matrix& aSn, AscanBlockPreprocessed getAscanBlockPreprocessed(Parser* aParser, const Aurora::Matrix& aMp, const Aurora::Matrix& aSl, const Aurora::Matrix& aSn,
const Aurora::Matrix& aRl, const Aurora::Matrix& aRn, GeometryInfo& aGeom, const MeasurementInfo& aMeasInfo, const Aurora::Matrix& aRl, const Aurora::Matrix& aRn, GeometryInfo& aGeom, const MeasurementInfo& aMeasInfo,
bool aApplyFilter, bool aTransReco); bool aApplyFilter, bool aTransReco);
struct AscanBlockPreprocessedCuda
{
Aurora::CudaMatrix ascanBlockPreprocessed;
Aurora::Matrix mpBlock;
Aurora::Matrix slBlock;
Aurora::Matrix snBlock;
Aurora::Matrix rlBlock;
Aurora::Matrix rnBlock;
Aurora::Matrix senderPositionBlock;
Aurora::Matrix receiverPositionBlock;
Aurora::CudaMatrix gainBlock;
};
AscanBlockPreprocessedCuda getAscanBlockPreprocessedCuda(Parser* aParser, const Aurora::Matrix& aMp, const Aurora::Matrix& aSl, const Aurora::Matrix& aSn,
const Aurora::Matrix& aRl, const Aurora::Matrix& aRn, GeometryInfo& aGeom, const MeasurementInfo& aMeasInfo,
bool aApplyFilter, bool aTransReco);
} }

View File

@@ -70,13 +70,13 @@ AscanBlock Recon::getAscanBlock(Parser* aParser, const Aurora::Matrix& aMp, cons
for(int slIndex=0; slIndex<aSl.getDataSize();++slIndex) for(int slIndex=0; slIndex<aSl.getDataSize();++slIndex)
{ {
OneTasAScanData oneTasData = aParser->getOneTasAscanDataOfMotorPosition(aSl[slIndex]); OneTasAScanData oneTasData = aParser->getOneTasAscanDataOfMotorPosition(aSl[slIndex]);
#pragma omp parallel for
for(int snIndex=0; snIndex<aSn.getDataSize();++snIndex) for(int snIndex=0; snIndex<aSn.getDataSize();++snIndex)
{ {
//int mapperIndex = 0; //int mapperIndex = 0;
#pragma omp parallel for //#pragma omp parallel for
for(int rlIndex=0; rlIndex<aRl.getDataSize();++rlIndex) for(int rlIndex=0; rlIndex<aRl.getDataSize();++rlIndex)
{ {
for(int rnIndex=0; rnIndex<aRn.getDataSize(); ++rnIndex) for(int rnIndex=0; rnIndex<aRn.getDataSize(); ++rnIndex)
{ {
size_t mapperIndex = rnIndex + rlIndex*aRn.getDataSize(); size_t mapperIndex = rnIndex + rlIndex*aRn.getDataSize();

View File

@@ -6,8 +6,8 @@
namespace Recon namespace Recon
{ {
const std::string DEFAULT_CONFIG_PATH = "/home/UR/ConfigFiles/"; const std::string DEFAULT_CONFIG_PATH = "/home/UR/ConfigFiles/";
const std::string DEFAULT_OUTPUT_PATH = "/home/UR/ReconResult/USCT_Result.mat"; const std::string DEFAULT_OUTPUT_PATH = "/home/UR/ReconResult/sun.mat";
const std::string DEFAULT_OUTPUT_FILENAME = "USCT_Result.mat"; const std::string DEFAULT_OUTPUT_FILENAME = "sun.mat";
std::string getPath(const std::string &aFullPath); std::string getPath(const std::string &aFullPath);
bool endsWithMat(const std::string &aStr); bool endsWithMat(const std::string &aStr);

View File

@@ -1,5 +1,6 @@
#include "preprocessAscanBlock.h" #include "preprocessAscanBlock.h"
#include "Function1D.h" #include "Function1D.h"
#include "Function1D.cuh"
#include <cstddef> #include <cstddef>
Aurora::Matrix Recon::preprocessAscanBlock(const Aurora::Matrix& aAscans, const MeasurementInfo& aMeasInfo) Aurora::Matrix Recon::preprocessAscanBlock(const Aurora::Matrix& aAscans, const MeasurementInfo& aMeasInfo)
@@ -20,4 +21,14 @@ Aurora::Matrix Recon::preprocessAscanBlock(const Aurora::Matrix& aAscans, const
// end // end
return result; return result;
}
Aurora::CudaMatrix Recon::preprocessAscanBlockCuda(const Aurora::CudaMatrix& aAscans, const MeasurementInfo& aMeasInfo)
{
if(aMeasInfo.ascanDataType == "float16")
{
return Aurora::convertfp16tofloatCuda(aAscans, aAscans.getDimSize(0), aAscans.getDimSize(1));
}
return aAscans;
} }

View File

@@ -7,6 +7,8 @@
namespace Recon namespace Recon
{ {
Aurora::Matrix preprocessAscanBlock(const Aurora::Matrix& aAscans, const MeasurementInfo& aMeasInfo); Aurora::Matrix preprocessAscanBlock(const Aurora::Matrix& aAscans, const MeasurementInfo& aMeasInfo);
Aurora::CudaMatrix preprocessAscanBlockCuda(const Aurora::CudaMatrix& aAscans, const MeasurementInfo& aMeasInfo);
} }
#endif #endif

View File

@@ -393,23 +393,23 @@ namespace Recon
nlohmann::json dataSelection = params.at("dataSelection"); nlohmann::json dataSelection = params.at("dataSelection");
if(dataSelection.contains("senderTasList")) if(dataSelection.contains("senderTasList"))
{ {
reflectParams::senderTasList = readToMatrix(dataSelection.at("senderTasList"), false); transParams::senderTasList = readToMatrix(dataSelection.at("senderTasList"), false);
} }
if(dataSelection.contains("receiverTasList")) if(dataSelection.contains("receiverTasList"))
{ {
reflectParams::receiverTasList = readToMatrix(dataSelection.at("receiverTasList"), false); transParams::receiverTasList = readToMatrix(dataSelection.at("receiverTasList"), false);
} }
if(dataSelection.contains("senderElementList")) if(dataSelection.contains("senderElementList"))
{ {
reflectParams::senderElementList = readToMatrix(dataSelection.at("senderElementList"), false); transParams::senderElementList = readToMatrix(dataSelection.at("senderElementList"), false);
} }
if(dataSelection.contains("receiverElementList")) if(dataSelection.contains("receiverElementList"))
{ {
reflectParams::receiverElementList = readToMatrix(dataSelection.at("receiverElementList"), false); transParams::receiverElementList = readToMatrix(dataSelection.at("receiverElementList"), false);
} }
if(dataSelection.contains("motorPos")) if(dataSelection.contains("motorPos"))
{ {
reflectParams::motorPos = readToMatrix(dataSelection.at("motorPos"), false); transParams::motorPos = readToMatrix(dataSelection.at("motorPos"), false);
} }
if(dataSelection.contains("filterSensitivity")) if(dataSelection.contains("filterSensitivity"))
{ {

View File

@@ -1,6 +1,23 @@
#include "AuroraDefs.h"
#include "CudaMatrix.h"
#include "Parser.h" #include "Parser.h"
#include "config/config.h" #include "config/config.h"
#include "log/notify.h" #include "log/notify.h"
#include "Data/ElementIndex.h"
#include "Matrix.h"
#include "Parser.h"
#include "ShotList/ShotList.h"
#include "config/config.h"
#include <algorithm>
#include <cstddef>
#include <cstdlib>
#include <mutex>
#include <ostream>
#include <thread>
#include <unistd.h>
#include <vector> #include <vector>
#define EIGEN_USE_MKL_ALL #define EIGEN_USE_MKL_ALL
@@ -12,15 +29,71 @@
2 is output path. 2 is output path.
3 is config file path. 3 is config file path.
*/ */
#include "Data/OneTasAScanData.h"
#include "Data/AScanData.h"
#include "Data/TasElementIndex.h"
#include "Data/ElectricIndex.h"
#include "Data/PatientData.h"
#include <iostream>
#include "Function.h"
#include "Function1D.h"
#include "Function2D.h"
#include "Function1D.cuh"
#include "Function2D.cuh"
#include "MatlabWriter.h"
#include "MatlabReader.h"
#include "/usr/local/cuda-10.1/targets/x86_64-linux/include/cufft.h"
#include </usr/local/cuda-10.1/targets/x86_64-linux/include/cuda_runtime.h>
#include "Aurora.h"
#include "common/dataBlockCreation/removeDataFromArrays.h"
#include <random>
#include <thrust/device_vector.h>
#include <thrust/execution_policy.h>
#include <thrust/sort.h>
#include <cuda_runtime.h>
#include <cuda_texture_types.h>
#include <texture_fetch_functions.h>
#include "reflectionReconstruction/preprocessData/imageExtrapolation.h"
#include <Data/PatientData.h>
#include "transmissionReconstruction/detection/getTransmissionData.cuh"
std::mutex mutex;
std::condition_variable condition;
std::vector<int> vector;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int argNum = 4; // Aurora::CudaMatrix fxDevice = Aurora::Matrix::fromRawData(new float[10]{1,2,3,4,5,6,7,8,9,10}, 5,1,1,Aurora::Complex).toDeviceMatrix();
// Aurora::CudaMatrix fhDevice = Aurora::Matrix::fromRawData(new float[10]{2,3,4,3,2,5,2,1,2,4}, 5,1,1,Aurora::Complex).toDeviceMatrix();
// Aurora::CudaMatrix fxReal = Aurora::real(fxDevice);
// Aurora::CudaMatrix fhReal = Aurora::real(fhDevice);
// Aurora::CudaMatrix fxImag = Aurora::imag(fxDevice);
// Aurora::CudaMatrix fhImag = Aurora::imag(fhDevice);
// Aurora::CudaMatrix real = fxReal *fhReal + fxImag * fhImag;
// Aurora::CudaMatrix image = fxImag * fhReal - fxReal * fhImag;
// Aurora::Matrix result = Aurora::complex(real, image).toHostMatrix();
// result.printf();
// result = getTransmissionDataSubFunction(fxDevice, fhDevice).toHostMatrix();
// result.printf();
// return 0;
int argNum = 4;
std::vector<std::string> args(argNum); std::vector<std::string> args(argNum);
args[0] = "/home/sun/20230418T141000/"; //args[0] = "/DataCenter/科正测试/00e04b741e9f_20231130T091019";
args[1] = "/home/sun/20230418T145123/"; //args[1] = "/DataCenter/科正测试/00e04b741e9f_20231130T091019";
args[0] = "/home/sun/20230418T145123/";
args[1] = "/home/sun/20230418T141000/";
//args[0] = "/home/krad/TestStore/00e04b741e9f_20231123T153138/";
//args[1] = "/home/krad/TestStore/00e04b741e9f_20231123T152045/";
args[2] = Recon::DEFAULT_OUTPUT_PATH; args[2] = Recon::DEFAULT_OUTPUT_PATH;
args[3] = Recon::DEFAULT_CONFIG_PATH; args[3] = Recon::DEFAULT_CONFIG_PATH;
// args[3] = "/home/UR/";
argc = argc <= argNum? argc-1 : argNum; argc = argc <= argNum? argc-1 : argNum;
for (int i = 0; i < argc; i++) for (int i = 0; i < argc; i++)
{ {

View File

@@ -0,0 +1,137 @@
#include "startReflectionReconstruction.h"
#include "Function.h"
#include "Function2D.h"
#include "Function3D.h"
#include "Matrix.h"
#include "MatlabWriter.h"
#include "common/getGeometryInfo.h"
#include "common/precalculateChannelList.h"
#include "common/dataBlockCreation/getAScanBlockPreprocessed.h"
#include "common/dataBlockCreation/removeDataFromArrays.h"
#include "log/notify.h"
#include "reflectionReconstruction/preprocessData/determineOptimalPulse.h"
#include "reflectionReconstruction/reconstructionSAFT/reconstructionSAFT.h"
#include "src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.h"
#include "config/config.h"
#include "log/log.h"
#include "CudaEnvInit.h"
#include <cstdio>
#include <iostream>
#include <queue>
#include <thread>
#include <vector>
using namespace Aurora;
using namespace Recon;
namespace
{
std::queue<preprocessAScanRResult> PRODUCER_PROCESSDATAS;
std::queue<AscanBlockPreprocessed> PRODUCER_BLOCKDATAS;
std::mutex PRODUCER_MUTEX;
std::condition_variable PRODUCER_CONDITION;
std::mutex CUSTOMER_MUTEX;
std::condition_variable CUSTOMER_CONDITION;
}
void producerThread( Parser* aParser, const Aurora::Matrix& aMotorPos,
const Aurora::Matrix& aSlList, const Aurora::Matrix& aSnList,
const Aurora::Matrix& aRlList, const Aurora::Matrix& aRnList,
GeometryInfo& aGeom, MeasurementInfo& aExpInfo, PreComputes& aPreComputes)
{
if(reflectParams::useOptPulse==1 && reflectParams::runReflectionReco)
{
aPreComputes.sincPeak_ft = determineOptimalPulse(aPreComputes.timeInterval, aExpInfo.expectedAScanLength);
}
printf(" - channel list");
auto channelList = precalculateChannelList(aRlList, aRnList, aExpInfo, aPreComputes);
size_t numScans = aMotorPos.getDataSize() * aSlList.getDataSize() *
aSnList.getDataSize() * aRlList.getDataSize() *
aRnList.getDataSize();
int numTakenScans = 0,numProcessedScans = 0,numPossibleScans = 0;
for(int i=0; i<aMotorPos.getDataSize(); ++i)
{
//#pragma omp parallel for num_threads(24)
for(int j=0; j<aSlList.getDataSize() / transParams::senderTASSize; ++j)
{
for(int k=0; k<aSnList.getDataSize() / transParams::senderElementSize; ++k)
{
Matrix mp = aMotorPos(i).toMatrix();
Matrix sl = aSlList.block(0, transParams::senderTASSize*j, transParams::senderTASSize*j+transParams::senderTASSize - 1);
Matrix sn = aSnList.block(0, transParams::senderElementSize*k, transParams::senderElementSize*k+transParams::senderElementSize - 1);
auto blockData = getAscanBlockPreprocessed(aParser, mp, sl, sn, aRlList, aRnList, aGeom, aExpInfo, true, false);
float* channelListSizeData = Aurora::malloc(2);
channelListSizeData[0] = channelList.getDimSize(0);
channelListSizeData[1] = channelList.getDimSize(1);
Matrix channelListSize = Matrix::New(channelListSizeData, 2, 1);
Matrix ind = sub2ind(channelListSize, {blockData.rlBlock, blockData.rnBlock});
size_t channelBlockSize = ind.getDataSize();
float* channelBlockData = Aurora::malloc(channelBlockSize);
for(size_t i=0; i<channelBlockSize; ++i)
{
channelBlockData[i] = channelList[ind[i] - 1];
}
Matrix channelBlock = Matrix::New(channelBlockData, 1, channelBlockSize);
RECON_INFO("start cpu---------preprocessAScanBlockForReflection");
auto preprocessData = preprocessAScanBlockForReflection(blockData.ascanBlockPreprocessed, blockData.mpBlock, blockData.slBlock,
blockData.snBlock, blockData.rlBlock, blockData.rnBlock, blockData.senderPositionBlock,
blockData.receiverPositionBlock, blockData.gainBlock, channelBlock, aExpInfo, aPreComputes);
PRODUCER_BLOCKDATAS.push(blockData);
PRODUCER_PROCESSDATAS.push(preprocessData);
}
}
}
}
Aurora::Matrix Recon::startReflectionReconstruction( Parser* aParser, int aSAFT_mode, const Aurora::Matrix& aMotorPos,
const Aurora::Matrix& aSlList, const Aurora::Matrix& aSnList,
const Aurora::Matrix& aRlList, const Aurora::Matrix& aRnList,
GeometryInfo& aGeom, TransRecos& aTransRecos,
MeasurementInfo& aExpInfo, PreComputes& aPreComputes)
{
printf("Reflection reconstruction is carried out.");
printf("Preperations for reconstructions.");
printf(" - reset GPUs");
for (size_t i = 0; i < reflectParams::gpuSelectionList.getDataSize(); i++)
{
std::string msg;
if (!resetGPUDevice((int)reflectParams::gpuSelectionList[i],msg))
{
std::cerr<<msg<<std::endl;
}
}
std::thread thread = std::thread(producerThread, aParser, aMotorPos, aSlList, aSnList, aRlList, aRnList, aGeom, aExpInfo, aPreComputes);
Matrix Env = Aurora::zeros((int)reflectParams::imageXYZ[0],(int)reflectParams::imageXYZ[1],(int)reflectParams::imageXYZ[2]);
for(int i=0; i<aMotorPos.getDataSize(); ++i)
{
//#pragma omp parallel for num_threads(24)
for(int j=0; j<aSlList.getDataSize() / transParams::senderTASSize; ++j)
{
for(int k=0; k<aSnList.getDataSize() / transParams::senderElementSize; ++k)
{
RECON_INFO("start gpu---------recontructSAFT");
Env = recontructSAFT(removeDataFromArrays(preprocessData.AscanBlock, preprocessData.usedData),
removeDataFromArrays(blockData.senderPositionBlock, preprocessData.usedData),
removeDataFromArrays(blockData.receiverPositionBlock, preprocessData.usedData),
removeDataFromArrays(blockData.mpBlock, preprocessData.usedData),
aSAFT_mode, aTransRecos, Env);
std::cout<<Env[0]<<"-" << Env[1] <<"-" << Env[2] <<"-" << Env[3]<<std::endl;
RECON_INFO("Reflection Reconstructon: " + std::to_string(j));
}
//Recon::notifyProgress(25+73*((j*i)/(aMotorPos.getDataSize() * aSlList.getDataSize())));
}
}
return Env;
}

View File

@@ -96,7 +96,7 @@ int Recon::startReconstructions(const std::string& aDataPath, const std::string&
TempInfo tempRef; TempInfo tempRef;
CEInfo ceRef; CEInfo ceRef;
Matrix transformationMatricesRef; Matrix transformationMatricesRef;
Recon::notifyProgress(1); //Recon::notifyProgress(1);
if(transParams::runTransmissionReco) if(transParams::runTransmissionReco)
{ {
expInfoRef = loadMeasurementInfos(&refParser); expInfoRef = loadMeasurementInfos(&refParser);
@@ -129,7 +129,7 @@ int Recon::startReconstructions(const std::string& aDataPath, const std::string&
transformationMatricesRef = Matrix(); transformationMatricesRef = Matrix();
motorPosAvailableRef = Matrix(); motorPosAvailableRef = Matrix();
} }
Recon::notifyProgress(2); //Recon::notifyProgress(2);
if(!ce.ce.isNull() && !ceRef.ce.isNull()) if(!ce.ce.isNull() && !ceRef.ce.isNull())
{ {
Matrix isEqual = (ce.ce == ceRef.ce); Matrix isEqual = (ce.ce == ceRef.ce);
@@ -156,12 +156,12 @@ int Recon::startReconstructions(const std::string& aDataPath, const std::string&
preComputes.matchedFilter = createMatchedFilter(ce.ceRef, ce.measuredCEUsed, reflectParams::findDefects, reconParams::removeOutliersFromCEMeasured, expInfo.Hardware); preComputes.matchedFilter = createMatchedFilter(ce.ceRef, ce.measuredCEUsed, reflectParams::findDefects, reconParams::removeOutliersFromCEMeasured, expInfo.Hardware);
} }
} }
Recon::notifyProgress(3); //Recon::notifyProgress(3);
if(expInfo.sampleRate != reflectParams::aScanReconstructionFrequency) if(expInfo.sampleRate != reflectParams::aScanReconstructionFrequency)
{ {
reflectParams::expectedAScanDataLength = ceil(expInfo.numberSamples * ((float)reflectParams::aScanReconstructionFrequency / expInfo.sampleRate)); reflectParams::expectedAScanDataLength = ceil(expInfo.numberSamples * ((float)reflectParams::aScanReconstructionFrequency / expInfo.sampleRate));
} }
Recon::notifyProgress(4); //Recon::notifyProgress(4);
TransmissionReconstructionResult transmissionResult; TransmissionReconstructionResult transmissionResult;
bool sosAvailable = false; bool sosAvailable = false;
bool attAvailable = false; bool attAvailable = false;
@@ -220,7 +220,7 @@ int Recon::startReconstructions(const std::string& aDataPath, const std::string&
GeometryInfo geomRef = getGeometryInfo(motorPosAvailableRef, transformationMatricesRef, rlList, rnList, slList, snList); GeometryInfo geomRef = getGeometryInfo(motorPosAvailableRef, transformationMatricesRef, rlList, rnList, slList, snList);
RECON_INFO("Start transmissionRecostruction."); RECON_INFO("Start transmissionRecostruction.");
Recon::notifyProgress(5); //Recon::notifyProgress(5);
transmissionResult = startTransmissionReconstruction(mp_inter, mpRef_inter, slList_inter, snList_inter, rlList_inter, rnList_inter, temp, tempRef, geom, geomRef, expInfo, expInfoRef, preComputes, &dataParser, &refParser); transmissionResult = startTransmissionReconstruction(mp_inter, mpRef_inter, slList_inter, snList_inter, rlList_inter, rnList_inter, temp, tempRef, geom, geomRef, expInfo, expInfoRef, preComputes, &dataParser, &refParser);
attAvailable = true; attAvailable = true;
sosAvailable = true; sosAvailable = true;
@@ -235,11 +235,11 @@ int Recon::startReconstructions(const std::string& aDataPath, const std::string&
Matrix recoSOS = transmissionResult.recoSOS; Matrix recoSOS = transmissionResult.recoSOS;
Matrix recoATT = transmissionResult.recoATT; Matrix recoATT = transmissionResult.recoATT;
precalcImageParameters(geom); precalcImageParameters(geom);
Recon::notifyProgress(21); //Recon::notifyProgress(21);
//检测可使用内存是否足够,输出警报用,todo //检测可使用内存是否足够,输出警报用,todo
//checkEnvAndMemory(reflectParams.imageInfos.IMAGE_XYZ); //checkEnvAndMemory(reflectParams.imageInfos.IMAGE_XYZ);
auto preProcessData = preprocessTransmissionReconstructionForReflection(recoSOS, recoATT, transmissionResult.ddmis, geom, temp); auto preProcessData = preprocessTransmissionReconstructionForReflection(recoSOS, recoATT, transmissionResult.ddmis, geom, temp);
Recon::notifyProgress(22); //Recon::notifyProgress(22);
Matrix mp_inter = intersect(motorPosAvailable, reflectParams::motorPos); Matrix mp_inter = intersect(motorPosAvailable, reflectParams::motorPos);
Matrix slList_inter = intersect(slList, reflectParams::senderTasList); Matrix slList_inter = intersect(slList, reflectParams::senderTasList);
Matrix snList_inter = intersect(snList, reflectParams::senderElementList); Matrix snList_inter = intersect(snList, reflectParams::senderElementList);
@@ -252,12 +252,12 @@ int Recon::startReconstructions(const std::string& aDataPath, const std::string&
preComputes.offset = estimateOffset(expInfo, ce, preComputes.matchedFilter); preComputes.offset = estimateOffset(expInfo, ce, preComputes.matchedFilter);
reflectParams::gpuSelectionList = reconParams::gpuSelectionList; reflectParams::gpuSelectionList = reconParams::gpuSelectionList;
Recon::notifyProgress(25); //Recon::notifyProgress(25);
RECON_INFO("Start reflectionRecostruction."); RECON_INFO("Start reflectionRecostruction.");
Matrix env = startReflectionReconstruction(&dataParser, preProcessData.saftMode, mp_inter, slList_inter, snList_inter, rlList_inter, rnList_inter, geom, preProcessData.transRecos, expInfo, preComputes); Matrix env = startReflectionReconstruction(&dataParser, preProcessData.saftMode, mp_inter, slList_inter, snList_inter, rlList_inter, rnList_inter, geom, preProcessData.transRecos, expInfo, preComputes);
writer.setMatrix(env, "reflect"); writer.setMatrix(env, "reflect");
//exporter.exportDICOM(env, Recon::DICOMExporter::REFL); //exporter.exportDICOM(env, Recon::DICOMExporter::REFL);
Recon::notifyProgress(99); //Recon::notifyProgress(99);
} }
writer.write(); writer.write();
return 0; return 0;

View File

@@ -7,7 +7,7 @@
namespace Recon namespace Recon
{ {
Aurora::Matrix distanceBetweenTwoPoints(Aurora::Matrix aPtsA, Aurora::Matrix aPtsB) Aurora::Matrix distanceBetweenTwoPoints(const Aurora::Matrix& aPtsA, const Aurora::Matrix& aPtsB)
{ {
return Aurora::sqrt(Aurora::sum((aPtsA-aPtsB)^2)); return Aurora::sqrt(Aurora::sum((aPtsA-aPtsB)^2));
} }

View File

@@ -3,8 +3,8 @@
#include "Matrix.h" #include "Matrix.h"
namespace Recon { namespace Recon {
Aurora::Matrix distanceBetweenTwoPoints(Aurora::Matrix aMPtsA, Aurora::Matrix distanceBetweenTwoPoints(const Aurora::Matrix& aMPtsA,
Aurora::Matrix aMPtsB); const Aurora::Matrix& aMPtsB);
Aurora::Matrix calculateWaterTemperature(Aurora::Matrix aMWaterTempS, Aurora::Matrix calculateWaterTemperature(Aurora::Matrix aMWaterTempS,
Aurora::Matrix aMWaterTempR, Aurora::Matrix aMWaterTempR,

View File

@@ -13,6 +13,7 @@
#include "common/getMeasurementMetaData.h" #include "common/getMeasurementMetaData.h"
#include "config/config.h" #include "config/config.h"
#include "calculateBankDetectAndHilbertTransformation.hpp" #include "calculateBankDetectAndHilbertTransformation.hpp"
#include "transmissionReconstruction/detection/detection.cuh"
using namespace Aurora; using namespace Aurora;
namespace Recon { namespace Recon {
@@ -414,34 +415,39 @@ namespace Recon {
return result; return result;
} }
DetectResult transmissionDetection(const Aurora::Matrix &AscanBlock, DetectResult transmissionDetection(const Aurora::CudaMatrix &AscanBlock,
const Aurora::Matrix &AscanRefBlock, const Aurora::CudaMatrix &AscanRefBlock,
const Aurora::Matrix &distBlock, const Aurora::CudaMatrix &distBlock,
const Aurora::Matrix &distRefBlock, const Aurora::CudaMatrix &distRefBlock,
const Aurora::Matrix &sosWaterBlock, const Aurora::Matrix &sosWaterBlock,
const Aurora::Matrix &sosWaterRefBlock, const Aurora::Matrix &sosWaterRefBlock,
float expectedSOSWater) { float expectedSOSWater) {
auto _sosWaterBlock = temperatureToSoundSpeed(sosWaterBlock, "marczak"); auto _sosWaterBlock = temperatureToSoundSpeed(sosWaterBlock, "marczak").toDeviceMatrix();
auto _sosWaterRefBlock = temperatureToSoundSpeed(sosWaterRefBlock, "marczak"); auto _sosWaterRefBlock = temperatureToSoundSpeed(sosWaterRefBlock, "marczak").toDeviceMatrix();
switch (Recon::transParams::version) { switch (Recon::transParams::version) {
case 1: { // case 1: {
return detectTofAndAttMex( // return detectTofAndAttMex(
AscanBlock, AscanRefBlock, distBlock, distRefBlock, // AscanBlock, AscanRefBlock, distBlock, distRefBlock,
_sosWaterBlock, _sosWaterRefBlock, Recon::transParams::resampleFactor, Recon::transParams::nThreads, // _sosWaterBlock, _sosWaterRefBlock, Recon::transParams::resampleFactor, Recon::transParams::nThreads,
expectedSOSWater, Recon::transParams::useTimeWindowing, // expectedSOSWater, Recon::transParams::useTimeWindowing,
Recon::transParams::aScanReconstructionFrequency, Recon::transParams::detectionWindowATT, // Recon::transParams::aScanReconstructionFrequency, Recon::transParams::detectionWindowATT,
Recon::transParams::offsetElectronic, Recon::transParams::detectionWindowSOS, Recon::transParams::minSpeedOfSound, // Recon::transParams::offsetElectronic, Recon::transParams::detectionWindowSOS, Recon::transParams::minSpeedOfSound,
Recon::transParams::maxSpeedOfSound, Recon::transParams::gaussWindow); // Recon::transParams::maxSpeedOfSound, Recon::transParams::gaussWindow);
} // }
case 2: // case 2:
default: default:
return detectTofAndAtt( auto r = detectTofAndAtt(
AscanBlock, AscanRefBlock, distBlock, distRefBlock, AscanBlock, AscanRefBlock, distBlock, distRefBlock,
_sosWaterBlock, _sosWaterRefBlock, Recon::transParams::resampleFactor, Recon::transParams::nThreads, _sosWaterBlock, _sosWaterRefBlock, Recon::transParams::resampleFactor, Recon::transParams::nThreads,
expectedSOSWater, Recon::transParams::useTimeWindowing, expectedSOSWater, Recon::transParams::useTimeWindowing,
Recon::transParams::aScanReconstructionFrequency, Recon::transParams::detectionWindowATT, Recon::transParams::aScanReconstructionFrequency, Recon::transParams::detectionWindowATT,
Recon::transParams::offsetElectronic, Recon::transParams::detectionWindowSOS, Recon::transParams::minSpeedOfSound, Recon::transParams::offsetElectronic, Recon::transParams::detectionWindowSOS, Recon::transParams::minSpeedOfSound,
Recon::transParams::maxSpeedOfSound, Recon::transParams::gaussWindow); Recon::transParams::maxSpeedOfSound, Recon::transParams::gaussWindow);
DetectResult ret;
ret.att = r.att.toHostMatrix();
ret.sosValue = r.sosValue.toHostMatrix();
ret.tof = r.tof.toHostMatrix();
return ret;
} }
} }
} }

View File

@@ -0,0 +1,323 @@
#include "CudaMatrix.h"
#include "detection.cuh"
#include <math.h>
#include <thrust/transform.h>
#include <thrust/execution_policy.h>
#include "Function1D.cuh"
#include "Function2D.cuh"
#include "Function3D.h"
__global__ void copyMatrixKernel(float* aStartPos1, float* aEndPos1,
float* aStartPos2, float* aEndPos2,
float* aIn1, float* aOut1,
float* aIn2, float* aOut2,
unsigned int aColElements){
unsigned int i = blockIdx.x;
unsigned int base_offset = i * aColElements;
unsigned int j = aStartPos1[i]-1+threadIdx.x;
for (int offset = 0; j+offset<aEndPos1[i]; offset+=blockDim.x) {
aOut1[j + base_offset + offset] = aIn1[j + base_offset + offset];
}
j = aStartPos2[i]-1+threadIdx.x;
for (int offset = 0; j+offset<aEndPos2[i]; offset+=blockDim.x) {
aOut2[j + base_offset + offset] = aIn2[j + base_offset + offset];
}
}
__global__ void setPosKernel(float* aStartPos1, float* aEndPos1,
float* aStartPos2, float* aEndPos2,
float* tof, float* tof2,
float* sizeAscan,
int sampleRate,
float offsetElectronicSamples,
int detectionWindowATT)
{
unsigned int i = blockIdx.x;
aStartPos1[i] = floor(fmaxf(tof[i] * sampleRate + offsetElectronicSamples, (float)1.0));
aEndPos1[i] = ceilf(fminf(sizeAscan[0], tof[i] * sampleRate + offsetElectronicSamples +
detectionWindowATT));
aStartPos2[i] = floorf(fmaxf(tof2[i], 1.0f));
aEndPos2[i] = ceilf(fminf(sizeAscan[1], tof2[i] + detectionWindowATT));
}
CudaMatrix Recon::calculateAttenuationCuda(const CudaMatrix &ascans,
const CudaMatrix &startPos,
const CudaMatrix &endPos,
const CudaMatrix &ascansRef,
const CudaMatrix &startPosRef,
const CudaMatrix &endPosRef){
auto ascans2 = Aurora::zerosCuda(ascans.getDimSize(0), ascans.getDimSize(1));
auto ascansRef2 = Aurora::zerosCuda(ascansRef.getDimSize(0), ascansRef.getDimSize(1));
copyMatrixKernel<<<ascans2.getDimSize(1),256>>>(startPos.getData(),endPos.getData(),
startPosRef.getData(), endPosRef.getData(),
ascans.getData(), ascans2.getData(),
ascansRef.getData(), ascansRef2.getData(),
ascans2.getDimSize(0));
auto pulseEnergy = Aurora::sum(ascans2^2);
auto pulseEnergyEmpty = Aurora::sum(ascansRef2^2);
return Aurora::log(pulseEnergyEmpty/pulseEnergy);
}
CudaMatrix
Recon::detectAttVectorizedCuda(const CudaMatrix &Ascan, const CudaMatrix &AscanRef,
const CudaMatrix &distRef,
const CudaMatrix &sosWaterRef,
const CudaMatrix &tof, int aScanReconstructionFrequency,
float offsetElectronic, int detectionWindowATT) {
auto sizeAscan = size(Ascan);
auto sampleRate = aScanReconstructionFrequency;
float offsetElectronicSamples = offsetElectronic * sampleRate;
auto envelopeOfAScan = Aurora::abs(Aurora::hilbert(Ascan));
auto envelopeOfReferenceAScan = Aurora::abs(hilbert(AscanRef));
auto tof2 = (distRef / sosWaterRef) * sampleRate + offsetElectronicSamples;
auto startPos = zerosCuda(Ascan.getDimSize(1), 1);
auto endPos = zerosCuda(Ascan.getDimSize(1), 1);
auto startPosRef = zerosCuda(Ascan.getDimSize(1), 1);
auto endPosRef = zerosCuda(Ascan.getDimSize(1), 1);
setPosKernel<<<Ascan.getDimSize(1),1>>>(startPos.getData(),
endPos.getData(), startPosRef.getData(), endPosRef.getData(),
tof.getData(), tof2.getData(), sizeAscan.getData(), sampleRate,
offsetElectronicSamples,detectionWindowATT);
return calculateAttenuationCuda(envelopeOfAScan, startPos, endPos,
envelopeOfReferenceAScan, startPosRef,
endPosRef);
}
CudaMatrix Recon::calculateSOSOffset(const CudaMatrix &sosBlock, float referenceSOS, const CudaMatrix &distBlock, float sampleRate){
auto offset = (distBlock / sosBlock - distBlock / referenceSOS) * sampleRate;
return offset;
}
Recon::SearchPositionC Recon::calculateStarEndSearchPosition(const CudaMatrix &aVDistBlock,
float minSpeedOfSound, float maxSpeedOfSound,
float sampleRate, float maxSample,
const CudaMatrix &aVSosOffsetBlock,
float startOffset, float segmentLenOffset)
{
auto startSearch = floor((aVDistBlock / maxSpeedOfSound)*sampleRate+aVSosOffsetBlock+startOffset);
auto lambda = [=] __device__ (const float& v){
float a = (uint)(v);
if(a<1) return 1.0f;
else if(a>maxSample) return maxSample;
return a;
};
thrust::transform(thrust::device, startSearch.getData(),startSearch.getData()+startSearch.getDataSize(),
startSearch.getData(),lambda);
auto endSearch = ceil(aVDistBlock/minSpeedOfSound*sampleRate+aVSosOffsetBlock+startOffset+segmentLenOffset);
thrust::transform(thrust::device, endSearch.getData(),endSearch.getData()+endSearch.getDataSize(),
endSearch.getData(),lambda);
Recon::SearchPositionC result;
result.startSearch = startSearch;
result.endSearch = endSearch;
return result;
}
__global__ void copyMatrixKernel(float* aStartPos1, float* aEndPos1,
float* aIn1, float* aOut1,
unsigned int aColElements){
unsigned int i = blockIdx.x;
unsigned int base_offset = i * aColElements;
unsigned int j = aStartPos1[i]-1+threadIdx.x;
for (int offset = 0; j+offset<aEndPos1[i]; offset+=blockDim.x) {
aOut1[j + base_offset + offset] = aIn1[j + base_offset + offset];
}
}
__device__ float getGuassValue(int aWidth,int aIndex){
float v = (-5.0f+(10.0f/(float)(aWidth-1))*aIndex);
return exp(-0.1f*(v*v));
}
__global__ void guassWindowKernel(float* aStartSearch,float* aEndSearch,
float* aIn1, float* aOut1, float* aExpectedPosWater,
unsigned int aColElements){
__shared__ unsigned int windowWidth;
__shared__ unsigned int base_offset;
__shared__ unsigned int j;
__shared__ unsigned int begin;
__shared__ unsigned int end ;
if(threadIdx.x == 0){
windowWidth = aEndSearch[blockIdx.x]-aStartSearch[blockIdx.x];
base_offset = blockIdx.x * aColElements;
j = aStartSearch[blockIdx.x]-1+threadIdx.x;
begin = roundf(aExpectedPosWater[blockIdx.x])- roundf(windowWidth/2)-1;
end = roundf(aExpectedPosWater[blockIdx.x])-roundf(windowWidth/2)+windowWidth-1;
}
for (int offset = 0; j+offset<aEndSearch[blockIdx.x]; offset+=blockDim.x) {
unsigned int threadAccIdx = j + offset;
if(threadAccIdx>=begin && threadAccIdx<end){
aOut1[threadAccIdx + base_offset] = aIn1[threadAccIdx + base_offset]*getGuassValue(windowWidth, threadAccIdx - begin);
}
else{
aOut1[threadAccIdx + base_offset] = aIn1[threadAccIdx + base_offset];
}
}
}
Recon::TimeWindowResultC Recon::applyTimeWindowing(const Aurora::CudaMatrix &AscanBlock, float sampleRate,
const Aurora::CudaMatrix &distBlock, const Aurora::CudaMatrix &sosBlock,
float expectedSOSWater, float startOffset, float segmentLenOffset,
float minSpeedOfSound, float maxSpeedOfSound, bool gaussWindow)
{
auto sosOffset = calculateSOSOffset(sosBlock, expectedSOSWater, distBlock, sampleRate);
auto calcResult = calculateStarEndSearchPosition(distBlock, minSpeedOfSound, maxSpeedOfSound, sampleRate,AscanBlock.getDimSize(0), sosOffset, startOffset, segmentLenOffset);
auto AscanBlockProcessed = zerosCuda(AscanBlock.getDimSize(0),AscanBlock.getDimSize(1));
if(gaussWindow)
{
auto expectedPosWater = (distBlock / expectedSOSWater) * sampleRate + startOffset;
guassWindowKernel<<<AscanBlock.getDimSize(1),256>>>(calcResult.startSearch.getData(),
calcResult.endSearch.getData(), AscanBlock.getData(), AscanBlockProcessed.getData(),
expectedPosWater.getData(), AscanBlock.getDimSize(0));
}
else{
copyMatrixKernel<<<AscanBlock.getDimSize(1),256>>>(calcResult.startSearch.getData(),
calcResult.endSearch.getData(),AscanBlock.getData(),AscanBlockProcessed.getData(),
AscanBlock.getDimSize(0));
}
Recon::TimeWindowResultC result;
result.startSearch = calcResult.startSearch;
result.AscanBlockProcessed = AscanBlockProcessed;
return result;
}
__device__ struct KVPair{
__device__ KVPair(){}
__device__ KVPair(int aIndex,float aValue):index(aIndex),value(aValue){};
__device__ KVPair(const KVPair& other){
index = other.index;
value = other.value;
}
int index;
float value;
};
__device__ KVPair maxKV(const KVPair& x, const KVPair& y){
return x.value>y.value ? x:y;
};
__global__ void findMaxIndexKernel(float* aInputData, unsigned int aColSize,float* aOutput, int aMaxlag){
//确定每个thread的index
unsigned int idx = blockIdx.x * aColSize + threadIdx.x;
__shared__ KVPair shared_data[256];
// 每个线程加载一个元素到共享内存
shared_data[threadIdx.x] = (threadIdx.x< aColSize) ? KVPair(threadIdx.x,aInputData[idx]) : KVPair(0,-FLT_MAX);
__syncthreads();
// 每个线程规约自己的分段将每个blockDim.x的值规约到数组最前面一段
for (int offset = blockDim.x; offset<aColSize; offset+=blockDim.x) {
if(threadIdx.x + offset<aColSize){
shared_data[threadIdx.x] = maxKV(shared_data[threadIdx.x], KVPair(threadIdx.x+offset, aInputData[idx + offset]));
}
__syncthreads();
}
// 规约最前面一段
for (int i = blockDim.x/2; i >0; i>>=1) {
if (threadIdx.x < i) {
shared_data[threadIdx.x] = maxKV(shared_data[threadIdx.x], shared_data[i + threadIdx.x]);
}
__syncthreads();
}
// 第一个线程存储每个分段的最大值到全局内存
if (threadIdx.x == 0) {
aOutput[blockIdx.x] = shared_data[0].index - aMaxlag;
}
}
int nextpow2(unsigned int value){
unsigned int compareValue = 2;
int result = 1;
while(compareValue<=value){
compareValue=compareValue<<1;
result++;
}
return result;
}
Recon::DetectResultC Recon::detectTofAndAtt(
const Aurora::CudaMatrix &AscanBlock, const Aurora::CudaMatrix &AscanRefBlock,
const Aurora::CudaMatrix &distBlock, const Aurora::CudaMatrix &distRefBlock,
const Aurora::CudaMatrix &sosWaterBlock,
const Aurora::CudaMatrix &sosWaterRefBlock,
int resampleFactor,int nthreads, float expectedSOSWater,
int useTimeWindowing, int aScanReconstructionFrequency,int detectionWindowATT,
float offsetElectronic, int detectionWindowSOS, float minSpeedOfSound,
float maxSpeedOfSound, bool gaussWindow)
{
auto sampleRate = aScanReconstructionFrequency;
float offsetElectronicSamples = offsetElectronic * sampleRate;
CudaMatrix diffStartSearch;
Recon::TimeWindowResultC timeResult1;
timeResult1.AscanBlockProcessed = AscanBlock;
Recon::TimeWindowResultC timeResult2;
timeResult2.AscanBlockProcessed = AscanRefBlock;
if (useTimeWindowing == 1) {
timeResult1 = applyTimeWindowing(
AscanBlock, sampleRate, distBlock, sosWaterBlock,
expectedSOSWater, offsetElectronicSamples, detectionWindowSOS,
minSpeedOfSound, maxSpeedOfSound, gaussWindow);
timeResult2 = applyTimeWindowing(
AscanRefBlock, sampleRate, distRefBlock, sosWaterRefBlock,
expectedSOSWater, offsetElectronicSamples, detectionWindowSOS,
minSpeedOfSound, maxSpeedOfSound, gaussWindow);
diffStartSearch = timeResult1.startSearch - timeResult2.startSearch;
}
auto _AscanBlock = timeResult1.AscanBlockProcessed;
auto _AscanRefBlock = timeResult2.AscanBlockProcessed;
int maxlag = 0;
CudaMatrix c, c1;
{
auto m = std::max(size(_AscanBlock, 1), size(_AscanRefBlock, 1));
maxlag =
std::max(size(_AscanBlock, 1), size(_AscanRefBlock, 1)) - 1;
auto mxl = std::min(maxlag, m - 1);
auto ceilLog2 = nextpow2(2 * m - 1);
auto m2 = pow(2, ceilLog2);
{
CudaMatrix c_1_2;
{
CudaMatrix c_1_1;
{
auto x = fft(_AscanBlock, m2);
auto y = fft(_AscanRefBlock, m2);
c_1_1 = x * conj(y);
}
c_1_2 = ifft(c_1_1);
}
c1 = real(c_1_2);
}
c = zerosCuda(mxl + mxl + 1, c1.getDimSize(1));
c.setBlock(0, 0, mxl-1, c1.block(0, m2-mxl,m2-1));
c.setBlock(0, mxl, mxl*2, c1.block(0, 0, mxl));
}
auto shiftInSamples = zerosCuda(1, c1.getDimSize(1));
findMaxIndexKernel<<<c.getDimSize(1),256>>>(c.getData(),c.getDimSize(0),shiftInSamples.getData(),maxlag);
if (useTimeWindowing) {
shiftInSamples = shiftInSamples - diffStartSearch;
}
auto tof = shiftInSamples / sampleRate + distBlock / sosWaterBlock;
auto sosValue = distBlock / tof;
Recon::DetectResultC result;
result.sosValue = sosValue;
auto tofRel = tof - distBlock / sosWaterBlock;
result.att = detectAttVectorizedCuda(
_AscanBlock, _AscanRefBlock, distRefBlock, sosWaterRefBlock,
tof, aScanReconstructionFrequency, offsetElectronic,
detectionWindowATT);
result.tof = tofRel;
return result;
}

View File

@@ -0,0 +1,53 @@
#ifndef __DETECTION_CUH__
#define __DETECTION_CUH__
#include "CudaMatrix.h"
using namespace Aurora;
namespace Recon {
struct SearchPositionC {
Aurora::CudaMatrix startSearch;
Aurora::CudaMatrix endSearch;
};
struct DetectResultC {
Aurora::CudaMatrix tof;
Aurora::CudaMatrix sosValue;
Aurora::CudaMatrix att;
};
struct TimeWindowResultC {
Aurora::CudaMatrix startSearch;
Aurora::CudaMatrix AscanBlockProcessed;
};
CudaMatrix calculateAttenuationCuda(const CudaMatrix &ascans,
const CudaMatrix &startPos,
const CudaMatrix &endPos,
const CudaMatrix &ascansRef,
const CudaMatrix &startPosRef,
const CudaMatrix &endPosRef);
CudaMatrix
detectAttVectorizedCuda(const CudaMatrix &Ascan, const CudaMatrix &AscanRef,
const CudaMatrix &distRef,
const CudaMatrix &sosWaterRef,
const CudaMatrix &tof, int aScanReconstructionFrequency,
float offsetElectronic, int detectionWindowATT);
TimeWindowResultC applyTimeWindowing(const Aurora::CudaMatrix &AscanBlock, float sampleRate,
const Aurora::CudaMatrix &distBlock, const Aurora::CudaMatrix &sosBlock,
float expectedSOSWater, float startOffset, float segmentLenOffset,
float minSpeedOfSound, float maxSpeedOfSound, bool gaussWindow);
SearchPositionC calculateStarEndSearchPosition(const CudaMatrix &aVDistBlock,
float minSpeedOfSound, float maxSpeedOfSound,
float sampleRate, float maxSample,
const CudaMatrix &aVSosOffsetBlock,
float startOffset, float segmentLenOffset);
CudaMatrix calculateSOSOffset(const CudaMatrix &sosBlock, float referenceSOS, const CudaMatrix &distBlock, float sampleRate);
DetectResultC detectTofAndAtt(
const Aurora::CudaMatrix &AscanBlock, const Aurora::CudaMatrix &AscanRefBlock,
const Aurora::CudaMatrix &distBlock, const Aurora::CudaMatrix &distRefBlock,
const Aurora::CudaMatrix &sosWaterBlock,
const Aurora::CudaMatrix &sosWaterRefBlock,
int resampleFactor,int nthreads, float expectedSOSWater,
int useTimeWindowing, int aScanReconstructionFrequency,int detectionWindowATT,
float offsetElectronic, int detectionWindowSOS, float minSpeedOfSound,
float maxSpeedOfSound, bool gaussWindow);
};
#endif // __DETECTION_H__

View File

@@ -75,8 +75,8 @@ detectTofAndAttMex(
DetectResult DetectResult
transmissionDetection( transmissionDetection(
const Aurora::Matrix &AscanBlock, const Aurora::Matrix &AscanRefBlock, const Aurora::CudaMatrix &AscanBlock, const Aurora::CudaMatrix &AscanRefBlock,
const Aurora::Matrix &distBlock, const Aurora::Matrix &distRefBlock, const Aurora::CudaMatrix &distBlock, const Aurora::CudaMatrix &distRefBlock,
const Aurora::Matrix &sosWaterBlock, const Aurora::Matrix &sosWaterRefBlock, float expectedSOSWater); const Aurora::Matrix &sosWaterBlock, const Aurora::Matrix &sosWaterRefBlock, float expectedSOSWater);
} // namespace Recon } // namespace Recon

View File

@@ -1,4 +1,7 @@
#include "getTransmissionData.h" #include "getTransmissionData.h"
#include "getTransmissionData.cuh"
#include "AuroraDefs.h"
#include "CudaMatrix.h"
#include "Function.h" #include "Function.h"
#include "Function1D.h" #include "Function1D.h"
#include "Function2D.h" #include "Function2D.h"
@@ -28,6 +31,11 @@
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
#include <cuda_runtime.h>
#include "Function1D.cuh"
#include "Function2D.cuh"
#include <sys/time.h>
using namespace Recon; using namespace Recon;
using namespace Aurora; using namespace Aurora;
@@ -42,8 +50,8 @@ namespace
Matrix waterTempBlock; Matrix waterTempBlock;
MetaInfos metaInfos; MetaInfos metaInfos;
Matrix ascanBlock; CudaMatrix ascanBlock;
Matrix ascanBlockRef; CudaMatrix ascanBlockRef;
Matrix dists; Matrix dists;
Matrix distRefBlock; Matrix distRefBlock;
Matrix waterTempRefBlock; Matrix waterTempRefBlock;
@@ -56,28 +64,59 @@ namespace
std::mutex PROCESS_BUFFER_MUTEX; std::mutex PROCESS_BUFFER_MUTEX;
std::condition_variable PROCESS_BUFFER_CONDITION; std::condition_variable PROCESS_BUFFER_CONDITION;
int BUFFER_COUNT = 0; int BUFFER_COUNT = 0;
int BUFFER_SIZE = 3; int BUFFER_SIZE = 4;//<=8
Matrix prepareAScansForTransmissionDetection(const Matrix& aAscanBlock, const Matrix& aGainBlock) void printTime()
{
struct timeval tpend;
gettimeofday(&tpend,NULL);
int secofday = (tpend.tv_sec + 3600 * 8 ) % 86400;
int hours = secofday / 3600;
int minutes = (secofday - hours * 3600 ) / 60;
int seconds = secofday % 60;
int milliseconds = tpend.tv_usec/1000;
std::cout<< hours << ":" <<minutes<<":"<<seconds<<"."<<milliseconds<<std::endl;
}
CudaMatrix prepareAScansForTransmissionDetection(const CudaMatrix& aAscanBlock, const CudaMatrix& aGainBlock)
{ {
Matrix result = aAscanBlock / repmat(aGainBlock, aAscanBlock.getDimSize(0), 1); CudaMatrix result = aAscanBlock / repmat(aGainBlock, aAscanBlock.getDimSize(0), 1);
result = result - repmat(mean(result,FunctionDirection::Column), result.getDimSize(0), 1); result = result - repmat(mean(result,FunctionDirection::Column), result.getDimSize(0), 1);
return result; return result;
} }
Aurora::CudaMatrix calculateSnr(const Aurora::CudaMatrix &aMDataBlock,
float aReferenceNoise) {
auto maxSignal = max(abs(aMDataBlock));
auto snrBlock = 10 * log(maxSignal / aReferenceNoise, 10);
return snrBlock;
}
BlockOfTransmissionData getBlockOfTransmissionData(const Matrix& aMp, const Matrix& aMpRef, const Matrix& aSl, const Matrix& aSn, const Matrix& aRlList, const Matrix& aRnList, BlockOfTransmissionData getBlockOfTransmissionData(const Matrix& aMp, const Matrix& aMpRef, const Matrix& aSl, const Matrix& aSn, const Matrix& aRlList, const Matrix& aRnList,
const TasTemps& aTasTemps, const Matrix& aExpectedSOSWater, GeometryInfo aGeom, GeometryInfo& aGeomRef, const TasTemps& aTasTemps, const Matrix& aExpectedSOSWater, GeometryInfo aGeom, GeometryInfo& aGeomRef,
const Matrix& aSnrRmsNoise, const Matrix& aSnrRmsNoiseRef, const MeasurementInfo& aExpInfo, const MeasurementInfo& aExpInfoRef, const Matrix& aSnrRmsNoise, const Matrix& aSnrRmsNoiseRef, const MeasurementInfo& aExpInfo, const MeasurementInfo& aExpInfoRef,
const PreComputes& aPreComputes, Parser* aParser, Parser* aParserRef) const PreComputes& aPreComputes, Parser* aParser, Parser* aParserRef)
{ {
BlockOfTransmissionData result; BlockOfTransmissionData result;
MetaInfos metaInfos; MetaInfos metaInfos;
auto blockData = getAscanBlockPreprocessed(aParser, aMp, aSl, aSn, aRlList, aRnList, aGeom, aExpInfo, true, true); //printTime();
auto blockDataRef = getAscanBlockPreprocessed(aParserRef, aMpRef, aSl, aSn, aRlList, aRnList, aGeomRef, aExpInfoRef, true, true); //2500ms
Matrix ascanBlock = prepareAScansForTransmissionDetection(blockData.ascanBlockPreprocessed, blockData.gainBlock); auto blockData = getAscanBlockPreprocessedCuda(aParser, aMp, aSl, aSn, aRlList, aRnList, aGeom, aExpInfo, true, true);
Matrix ascanBlockRef = prepareAScansForTransmissionDetection(blockDataRef.ascanBlockPreprocessed, blockDataRef.gainBlock); auto blockDataRef = getAscanBlockPreprocessedCuda(aParserRef, aMpRef, aSl, aSn, aRlList, aRnList, aGeomRef, aExpInfoRef, true, true);
blockData.ascanBlockPreprocessed = Matrix(); //printTime();
blockDataRef.ascanBlockPreprocessed = Matrix(); //180ms
// auto t1 = blockData.ascanBlockPreprocessed.toDeviceMatrix();
// auto t2 = blockDataRef.ascanBlockPreprocessed.toDeviceMatrix();
// auto t3 = blockData.gainBlock.toDeviceMatrix();
// auto t4 = blockDataRef.gainBlock.toDeviceMatrix();
//printTime();
//20ms
CudaMatrix ascanBlock = prepareAScansForTransmissionDetection(blockData.ascanBlockPreprocessed,blockData.gainBlock);
CudaMatrix ascanBlockRef = prepareAScansForTransmissionDetection(blockDataRef.ascanBlockPreprocessed,blockDataRef.gainBlock);
//printTime();
//20ms
blockData.ascanBlockPreprocessed = CudaMatrix();
blockDataRef.ascanBlockPreprocessed = CudaMatrix();
if(aExpInfo.Hardware == "USCT3dv3") if(aExpInfo.Hardware == "USCT3dv3")
{ {
Matrix channelList = precalculateChannelList(aRlList, aRnList, aExpInfo, aPreComputes); Matrix channelList = precalculateChannelList(aRlList, aRnList, aExpInfo, aPreComputes);
@@ -93,71 +132,48 @@ namespace
channelListBlockData[i] = channelList[ind[i] - 1]; channelListBlockData[i] = channelList[ind[i] - 1];
} }
Matrix channelListBlock = Matrix::New(channelListBlockData, 1, channelListBlockSize); Matrix channelListBlock = Matrix::New(channelListBlockData, 1, channelListBlockSize);
Matrix fx = fft(ascanBlock); //printTime();
float* fhData = Aurora::malloc(aExpInfo.matchedFilter.getDimSize(0) * channelListBlockSize, true); //20ms
Matrix fh = Matrix::New(fhData, aExpInfo.matchedFilter.getDimSize(0), channelListBlockSize, 1, Aurora::Complex); CudaMatrix fx = fft(ascanBlock);
size_t matchedFilterRowDataSize = aExpInfo.matchedFilter.getDimSize(0)*2; //printTime();
for(size_t i=0; i<channelListBlockSize; ++i) //50ms
{ // float* fhData = nullptr;
cblas_scopy(matchedFilterRowDataSize, aExpInfo.matchedFilter.getData() + (size_t)(channelListBlock[i] - 1) * matchedFilterRowDataSize, 1 , fhData ,1); // cudaMalloc((void**)&fhData, sizeof(float) * aExpInfo.matchedFilter.getDimSize(0) * channelListBlockSize * Aurora::Complex);
fhData += matchedFilterRowDataSize; // CudaMatrix fh = CudaMatrix::fromRawData(fhData, aExpInfo.matchedFilter.getDimSize(0), channelListBlockSize, 1, Aurora::Complex);
} // size_t matchedFilterRowDataSize = aExpInfo.matchedFilter.getDimSize(0)*2;
// Matrix fxReal = Aurora::real(fx); // for(size_t i=0; i<channelListBlockSize; ++i)
// Matrix fhReal = Aurora::real(fh); // {
// Matrix fxImag = Aurora::imag(fx); // cudaMemcpy(fhData, aExpInfo.matchedFilter.getData() + (size_t)(channelListBlock[i] - 1) * matchedFilterRowDataSize, sizeof(float) * matchedFilterRowDataSize, cudaMemcpyHostToDevice);
// Matrix fhImag = Aurora::imag(fh); // fhData += matchedFilterRowDataSize;
// Matrix real = fxReal * fhReal + fxImag * fhImag; // }
// Matrix image = fxImag * fhReal - fxReal * fhImag; Aurora::CudaMatrix matchedFilterDevice = aExpInfo.matchedFilter.toDeviceMatrix();
float* value1 = Aurora::malloc(fx.getDataSize()); Aurora::CudaMatrix channelListBlockDevice = channelListBlock.toDeviceMatrix();
vsMulI(fx.getDataSize(), fx.getData(), 2, fh.getData(), 2, value1, 1); Aurora::CudaMatrix fh = createFhMatrix(matchedFilterDevice, channelListBlockDevice);
float* value2 = Aurora::malloc(fx.getDataSize()); //printTime();
vsMulI(fx.getDataSize(), fx.getData() + 1, 2, fh.getData() + 1, 2, value2, 1); //20ms
float* realData = Aurora::malloc(fx.getDataSize()); CudaMatrix complex = getTransmissionDataSubFunction(fx, fh);
vsAdd(fx.getDataSize(), value1, value2, realData);
Matrix real = Matrix::New(realData, fx.getDimSize(0), fx.getDimSize(1));
vsMulI(fx.getDataSize(), fx.getData() + 1, 2, fh.getData(), 2, value1, 1);
vsMulI(fx.getDataSize(), fx.getData(), 2, fh.getData() + 1, 2, value2, 1);
float* imagData = Aurora::malloc(fx.getDataSize());
vsSub(fx.getDataSize(), value1, value2, imagData);
Matrix image = Matrix::New(imagData, fx.getDimSize(0), fx.getDimSize(1));
float* complexData = Aurora::malloc(real.getDataSize(), true);
cblas_scopy(real.getDataSize(), real.getData(), 1 , complexData ,2);
cblas_scopy(image.getDataSize(), image.getData(), 1 , complexData + 1 ,2);
Matrix complex = Matrix::New(complexData, real.getDimSize(0), real.getDimSize(1), 1, Aurora::Complex);
ascanBlock = Aurora::real(ifft(complex)); ascanBlock = Aurora::real(ifft(complex));
//printTime();
//20s
fx = fft(ascanBlockRef); fx = fft(ascanBlockRef);
fhData = Aurora::malloc(aExpInfoRef.matchedFilter.getDimSize(0) * channelListBlockSize, true); //printTime();
fh = Matrix::New(fhData, aExpInfoRef.matchedFilter.getDimSize(0), channelListBlockSize, 1, Aurora::Complex); //50ms
matchedFilterRowDataSize = aExpInfoRef.matchedFilter.getDimSize(0)*2; // cudaMalloc((void**)&fhData, sizeof(float) * aExpInfo.matchedFilter.getDimSize(0) * channelListBlockSize * Aurora::Complex);
for(size_t i=0; i<channelListBlockSize; ++i) // fh = CudaMatrix::fromRawData(fhData, aExpInfoRef.matchedFilter.getDimSize(0), channelListBlockSize, 1, Aurora::Complex);
{ // matchedFilterRowDataSize = aExpInfoRef.matchedFilter.getDimSize(0)*2;
cblas_scopy(matchedFilterRowDataSize, aExpInfoRef.matchedFilter.getData() + (size_t)(channelListBlock[i] - 1) * matchedFilterRowDataSize, 1 , fhData ,1); // for(size_t i=0; i<channelListBlockSize; ++i)
fhData += matchedFilterRowDataSize; // {
} // cudaMemcpy(fhData, aExpInfoRef.matchedFilter.getData() + (size_t)(channelListBlock[i] - 1) * matchedFilterRowDataSize, sizeof(float) * matchedFilterRowDataSize, cudaMemcpyHostToDevice);
// real = Aurora::real(fx) * Aurora::real(fh) + Aurora::imag(fx) * Aurora::imag(fh); // fhData += matchedFilterRowDataSize;
// image = Aurora::imag(fx) * Aurora::real(fh) - Aurora::real(fx) * Aurora::imag(fh); // }
vsMulI(fx.getDataSize(), fx.getData(), 2, fh.getData(), 2, value1, 1); matchedFilterDevice = aExpInfoRef.matchedFilter.toDeviceMatrix();
vsMulI(fx.getDataSize(), fx.getData() + 1, 2, fh.getData() + 1, 2, value2, 1); fh = createFhMatrix(matchedFilterDevice, channelListBlockDevice);
realData = Aurora::malloc(fx.getDataSize()); //printTime();
vsAdd(fx.getDataSize(), value1, value2, realData); //20ms
real = Matrix::New(realData, fx.getDimSize(0), fx.getDimSize(1)); complex = getTransmissionDataSubFunction(fx, fh);
vsMulI(fx.getDataSize(), fx.getData() + 1, 2, fh.getData(), 2, value1, 1);
vsMulI(fx.getDataSize(), fx.getData(), 2, fh.getData() + 1, 2, value2, 1);
imagData = Aurora::malloc(fx.getDataSize());
vsSub(fx.getDataSize(), value1, value2, imagData);
image = Matrix::New(imagData, fx.getDimSize(0), fx.getDimSize(1));
Aurora::free(value1);
Aurora::free(value2);
complexData = Aurora::malloc(real.getDataSize(), true);
cblas_scopy(real.getDataSize(), real.getData(), 1 , complexData ,2);
cblas_scopy(image.getDataSize(), image.getData(), 1 , complexData + 1 ,2);
complex = Matrix::New(complexData, real.getDimSize(0), real.getDimSize(1), 1, Aurora::Complex);
ascanBlockRef = Aurora::real(ifft(complex)); ascanBlockRef = Aurora::real(ifft(complex));
//printTime();
//20ms
} }
else else
{ {
@@ -167,24 +183,27 @@ namespace
if(transParams::applyCalib) if(transParams::applyCalib)
{ {
metaInfos.snrValues = calculateSnr(ascanBlock, aSnrRmsNoise[0]); metaInfos.snrValues = calculateSnr(ascanBlock, aSnrRmsNoise[0]).toHostMatrix();
metaInfos.snrValuesRef = calculateSnr(ascanBlockRef, aSnrRmsNoiseRef[0]); metaInfos.snrValuesRef = calculateSnr(ascanBlockRef, aSnrRmsNoiseRef[0]).toHostMatrix();
} }
// printTime();
//3ms
Matrix dists = distanceBetweenTwoPoints(blockData.senderPositionBlock, blockData.receiverPositionBlock); Matrix dists = distanceBetweenTwoPoints(blockData.senderPositionBlock, blockData.receiverPositionBlock);
Matrix distRefBlock = distanceBetweenTwoPoints(blockDataRef.senderPositionBlock, blockDataRef.receiverPositionBlock); Matrix distRefBlock = distanceBetweenTwoPoints(blockDataRef.senderPositionBlock, blockDataRef.receiverPositionBlock);
//printTime();
//2ms
Matrix waterTempBlock = calculateWaterTemperature(aTasTemps.waterTempPreCalc_sl, aTasTemps.waterTempPreCalc_rl, blockData.slBlock, blockData.rlBlock, blockData.mpBlock); Matrix waterTempBlock = calculateWaterTemperature(aTasTemps.waterTempPreCalc_sl, aTasTemps.waterTempPreCalc_rl, blockData.slBlock, blockData.rlBlock, blockData.mpBlock);
Matrix waterTempRefBlock = calculateWaterTemperature(aTasTemps.waterTempRefPreCalc_sl, aTasTemps.waterTempRefPreCalc_rl, blockData.slBlock, blockData.rlBlock, blockDataRef.mpBlock); Matrix waterTempRefBlock = calculateWaterTemperature(aTasTemps.waterTempRefPreCalc_sl, aTasTemps.waterTempRefPreCalc_rl, blockData.slBlock, blockData.rlBlock, blockDataRef.mpBlock);
// printTime();
if(transParams::saveDetection || transParams::outlierOnTasDetection || transParams::saveDebugInfomation) // 1ms
{ // if(transParams::saveDetection || transParams::outlierOnTasDetection || transParams::saveDebugInfomation)
metaInfos.mpBlock = blockData.mpBlock; // {
metaInfos.slBlock = blockData.slBlock; // metaInfos.mpBlock = blockData.mpBlock;
metaInfos.snBlock = blockData.snBlock; // metaInfos.slBlock = blockData.slBlock;
metaInfos.rlBlock = blockData.rlBlock; // metaInfos.snBlock = blockData.snBlock;
metaInfos.rnBlock = blockData.rnBlock; // metaInfos.rlBlock = blockData.rlBlock;
} // metaInfos.rnBlock = blockData.rnBlock;
// }
result.metaInfos = metaInfos; result.metaInfos = metaInfos;
result.senderBlock = blockData.senderPositionBlock; result.senderBlock = blockData.senderPositionBlock;
result.receiverBlock = blockData.receiverPositionBlock; result.receiverBlock = blockData.receiverPositionBlock;
@@ -199,7 +218,7 @@ namespace
// DetectResult detect = transmissionDetection(ascanBlock, ascanBlockRef, dists, distRefBlock, waterTempBlock, waterTempRefBlock, aExpectedSOSWater[0]); // DetectResult detect = transmissionDetection(ascanBlock, ascanBlockRef, dists, distRefBlock, waterTempBlock, waterTempRefBlock, aExpectedSOSWater[0]);
// result.attData = detect.att; // result.attData = detect.att;
// result.tofData = detect.tof; // result.tofData = detect.tof;
//printTime();
return result; return result;
} }
@@ -208,8 +227,9 @@ namespace
void getBlockOfTransmissionDataInThread(size_t aIndex, const Matrix& aMp, const Matrix& aMpRef, const Matrix& aSl, const Matrix& aSn, const Matrix& aRlList, const Matrix& aRnList, void getBlockOfTransmissionDataInThread(size_t aIndex, const Matrix& aMp, const Matrix& aMpRef, const Matrix& aSl, const Matrix& aSn, const Matrix& aRlList, const Matrix& aRnList,
const TasTemps& aTasTemps, const Matrix& aExpectedSOSWater, GeometryInfo aGeom, GeometryInfo aGeomRef, const TasTemps& aTasTemps, const Matrix& aExpectedSOSWater, GeometryInfo aGeom, GeometryInfo aGeomRef,
const Matrix& aSnrRmsNoise, const Matrix& aSnrRmsNoiseRef, const MeasurementInfo& aExpInfo, const MeasurementInfo& aExpInfoRef, const Matrix& aSnrRmsNoise, const Matrix& aSnrRmsNoiseRef, const MeasurementInfo& aExpInfo, const MeasurementInfo& aExpInfoRef,
const PreComputes& aPreComputes, Parser* aParser, Parser* aParserRef) const PreComputes& aPreComputes, Parser* aParser, Parser* aParserRef, unsigned int aGPUId)
{ {
cudaSetDevice(aGPUId);
auto buffer = getBlockOfTransmissionData(aMp, aMpRef, aSl, aSn, aRlList, aRnList, aTasTemps, auto buffer = getBlockOfTransmissionData(aMp, aMpRef, aSl, aSn, aRlList, aRnList, aTasTemps,
aExpectedSOSWater, aGeom, aGeomRef, aSnrRmsNoise, aSnrRmsNoiseRef, aExpectedSOSWater, aGeom, aGeomRef, aSnrRmsNoise, aSnrRmsNoiseRef,
aExpInfo, aExpInfoRef, aPreComputes, aParser, aParserRef); aExpInfo, aExpInfoRef, aPreComputes, aParser, aParserRef);
@@ -245,7 +265,7 @@ void createThreadForGetBlockOfTransmissionData(const Matrix& aMotorPos, const M
CREATE_BUFFER_CONDITION.wait(lock, []{return BUFFER_COUNT<BUFFER_SIZE;}); CREATE_BUFFER_CONDITION.wait(lock, []{return BUFFER_COUNT<BUFFER_SIZE;});
++BUFFER_COUNT; ++BUFFER_COUNT;
lock.unlock(); lock.unlock();
speedUpThread[index] = std::thread(getBlockOfTransmissionDataInThread,index,mp,mpRef,sl,sn,aRlList,aRnList,aTasTemps,aExpectedSOSWater,aGeom,aGeomRef,aSnrRmsNoise,aSnrRmsNoiseRef,aExpInfo,aExpInfoRef,aPreComputes,aParser, aParserRef); speedUpThread[index] = std::thread(getBlockOfTransmissionDataInThread,index,mp,mpRef,sl,sn,aRlList,aRnList,aTasTemps,aExpectedSOSWater,aGeom,aGeomRef,aSnrRmsNoise,aSnrRmsNoiseRef,aExpInfo,aExpInfoRef,aPreComputes,aParser, aParserRef, index % BUFFER_SIZE);
} }
} }
} }
@@ -334,8 +354,9 @@ TransmissionData Recon::getTransmissionData(const Aurora::Matrix& aMotorPos, con
lock.unlock(); lock.unlock();
auto blockData = BLOCK_OF_TRANSIMISSIONDARA_BUFFER[std::to_string(index)]; auto blockData = BLOCK_OF_TRANSIMISSIONDARA_BUFFER[std::to_string(index)];
cudaSetDevice(index % BUFFER_SIZE);
DetectResult detect = transmissionDetection( blockData.ascanBlock, blockData.ascanBlockRef, DetectResult detect = transmissionDetection( blockData.ascanBlock, blockData.ascanBlockRef,
blockData.dists, blockData.distRefBlock, blockData.dists.toDeviceMatrix(), blockData.distRefBlock.toDeviceMatrix(),
blockData.waterTempBlock, blockData.waterTempRefBlock, blockData.waterTempBlock, blockData.waterTempRefBlock,
aTemp.expectedSOSWater[0]); aTemp.expectedSOSWater[0]);
blockData.attData = detect.att; blockData.attData = detect.att;
@@ -355,14 +376,14 @@ TransmissionData Recon::getTransmissionData(const Aurora::Matrix& aMotorPos, con
cblas_scopy(numUsedData, transmissionBlock.attData.getData(), 1, attDataTotal.getData() + numData, 1); cblas_scopy(numUsedData, transmissionBlock.attData.getData(), 1, attDataTotal.getData() + numData, 1);
cblas_scopy(numUsedData, transmissionBlock.waterTempBlock.getData(), 1, waterTempList.getData() + numData, 1); cblas_scopy(numUsedData, transmissionBlock.waterTempBlock.getData(), 1, waterTempList.getData() + numData, 1);
if(transParams::saveDetection || transParams::outlierOnTasDetection || transParams::saveDebugInfomation) // if(transParams::saveDetection || transParams::outlierOnTasDetection || transParams::saveDebugInfomation)
{ // {
cblas_scopy(numUsedData, transmissionBlock.metaInfos.mpBlock.getData(), 1, mpBlockTotal.getData() + numData, 1); // cblas_scopy(numUsedData, transmissionBlock.metaInfos.mpBlock.getData(), 1, mpBlockTotal.getData() + numData, 1);
cblas_scopy(numUsedData, transmissionBlock.metaInfos.slBlock.getData(), 1, slBlockTotal.getData() + numData, 1); // cblas_scopy(numUsedData, transmissionBlock.metaInfos.slBlock.getData(), 1, slBlockTotal.getData() + numData, 1);
cblas_scopy(numUsedData, transmissionBlock.metaInfos.snBlock.getData(), 1, snBlockTotal.getData() + numData, 1); // cblas_scopy(numUsedData, transmissionBlock.metaInfos.snBlock.getData(), 1, snBlockTotal.getData() + numData, 1);
cblas_scopy(numUsedData, transmissionBlock.metaInfos.rlBlock.getData(), 1, rlBlockTotal.getData() + numData, 1); // cblas_scopy(numUsedData, transmissionBlock.metaInfos.rlBlock.getData(), 1, rlBlockTotal.getData() + numData, 1);
cblas_scopy(numUsedData, transmissionBlock.metaInfos.rnBlock.getData(), 1, rnBlockTotal.getData() + numData, 1); // cblas_scopy(numUsedData, transmissionBlock.metaInfos.rnBlock.getData(), 1, rnBlockTotal.getData() + numData, 1);
} // }
numData += numUsedData; numData += numUsedData;
std::unique_lock<std::mutex> lockBufferCount(CREATE_BUFFER_MUTEX); std::unique_lock<std::mutex> lockBufferCount(CREATE_BUFFER_MUTEX);
BLOCK_OF_TRANSIMISSIONDARA_BUFFER.erase(std::to_string(index)); BLOCK_OF_TRANSIMISSIONDARA_BUFFER.erase(std::to_string(index));
@@ -371,7 +392,7 @@ TransmissionData Recon::getTransmissionData(const Aurora::Matrix& aMotorPos, con
std::cout<<"Remove: "<<index<<std::endl; std::cout<<"Remove: "<<index<<std::endl;
CREATE_BUFFER_CONDITION.notify_one(); CREATE_BUFFER_CONDITION.notify_one();
} }
Recon::notifyProgress(6+10*((i+1)*(j+1)/(aMotorPos.getDataSize()*(aSlList.getDataSize()/ transParams::senderTASSize)))); //Recon::notifyProgress(6+10*((i+1)*(j+1)/(aMotorPos.getDataSize()*(aSlList.getDataSize()/ transParams::senderTASSize))));
} }
} }
speedUpThread.join(); speedUpThread.join();
@@ -399,14 +420,14 @@ TransmissionData Recon::getTransmissionData(const Aurora::Matrix& aMotorPos, con
tofDataTotal = removeDataFromArrays(tofDataTotal, filter); tofDataTotal = removeDataFromArrays(tofDataTotal, filter);
attDataTotal = removeDataFromArrays(attDataTotal, filter); attDataTotal = removeDataFromArrays(attDataTotal, filter);
waterTempList = removeDataFromArrays(waterTempList, filter); waterTempList = removeDataFromArrays(waterTempList, filter);
if(transParams::saveDebugInfomation || transParams::outlierOnTasDetection || transParams::saveDetection) // if(transParams::saveDebugInfomation || transParams::outlierOnTasDetection || transParams::saveDetection)
{ // {
mpBlockTotal = removeDataFromArrays(mpBlockTotal, filter); // mpBlockTotal = removeDataFromArrays(mpBlockTotal, filter);
slBlockTotal = removeDataFromArrays(slBlockTotal, filter); // slBlockTotal = removeDataFromArrays(slBlockTotal, filter);
snBlockTotal = removeDataFromArrays(snBlockTotal, filter); // snBlockTotal = removeDataFromArrays(snBlockTotal, filter);
rlBlockTotal = removeDataFromArrays(rlBlockTotal, filter); // rlBlockTotal = removeDataFromArrays(rlBlockTotal, filter);
rnBlockTotal = removeDataFromArrays(rnBlockTotal, filter); // rnBlockTotal = removeDataFromArrays(rnBlockTotal, filter);
} // }
Matrix valid; Matrix valid;
if(transParams::applyCalib) if(transParams::applyCalib)
@@ -432,14 +453,14 @@ TransmissionData Recon::getTransmissionData(const Aurora::Matrix& aMotorPos, con
} }
dataInfno.findDefect = Matrix::New(findDefectData, 1, findDefectDataIndex); dataInfno.findDefect = Matrix::New(findDefectData, 1, findDefectDataIndex);
if(transParams::saveDebugInfomation) // if(transParams::saveDebugInfomation)
{ // {
dataInfno.sn = snBlockTotal; // dataInfno.sn = snBlockTotal;
dataInfno.sl = slBlockTotal; // dataInfno.sl = slBlockTotal;
dataInfno.rn = rnBlockTotal; // dataInfno.rn = rnBlockTotal;
dataInfno.rl = rlBlockTotal; // dataInfno.rl = rlBlockTotal;
dataInfno.mp = mpBlockTotal; // dataInfno.mp = mpBlockTotal;
} // }
tofDataTotal = removeDataFromArrays(tofDataTotal, valid); tofDataTotal = removeDataFromArrays(tofDataTotal, valid);
attDataTotal = removeDataFromArrays(attDataTotal, valid); attDataTotal = removeDataFromArrays(attDataTotal, valid);

View File

@@ -0,0 +1,60 @@
#include "AuroraDefs.h"
#include "getTransmissionData.cuh"
#include <cstdio>
#include <cuda_runtime.h>
const int THREADS_PER_BLOCK = 256;
__global__ void getTransmissionDataSubFunctionKernel(float* aFx, float* aFh, float* aOutput, unsigned int aSize)
{
unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < aSize)
{
unsigned int realIndex = idx * 2;
unsigned int imagIndex = realIndex + 1;
float fxReal = aFx[realIndex];
float fhReal = aFh[realIndex];
float fxImag = aFx[imagIndex];
float fhImag = aFh[imagIndex];
aOutput[realIndex] = fxReal * fhReal + fxImag * fhImag;
aOutput[2*idx + 1] = fxImag * fhReal - fxReal * fhImag;
}
}
Aurora::CudaMatrix getTransmissionDataSubFunction(const Aurora::CudaMatrix& aFxMatrix, const Aurora::CudaMatrix& aFhMatrix)
{
size_t size = aFxMatrix.getDataSize();
float* data = nullptr;
cudaMalloc((void**)&data, sizeof(float) * size * Aurora::Complex);
int blocksPerGrid = (size + THREADS_PER_BLOCK - 1) / THREADS_PER_BLOCK;
getTransmissionDataSubFunctionKernel<<<blocksPerGrid, THREADS_PER_BLOCK>>>(aFxMatrix.getData(), aFhMatrix.getData(), data, size);
cudaDeviceSynchronize();
return Aurora::CudaMatrix::fromRawData(data, aFxMatrix.getDimSize(0), aFxMatrix.getDimSize(1), aFxMatrix.getDimSize(2), Aurora::Complex);
}
__global__ void createFhMatrixKernel(float* aMatchedFilter, float* aChannelListBlock, float* aOutput, unsigned int aRowSize)
{
for(unsigned int i=0; i< std::ceil((float)aRowSize / (float)THREADS_PER_BLOCK); ++i)
{
unsigned int index = i * THREADS_PER_BLOCK + threadIdx.x;
if(index < aRowSize)
{
unsigned int outPutComplexIndex = 2 * (blockIdx.x * aRowSize + index);
unsigned int inputComplexIndex = 2 * ((aChannelListBlock[blockIdx.x] - 1) * aRowSize + index);
aOutput[outPutComplexIndex] = aMatchedFilter[inputComplexIndex];
aOutput[outPutComplexIndex + 1] = aMatchedFilter[inputComplexIndex + 1];
}
}
}
Aurora::CudaMatrix createFhMatrix(const Aurora::CudaMatrix& aMatchedFilter, const Aurora::CudaMatrix& aChannelListBlock)
{
size_t columnSize = aChannelListBlock.getDataSize();
size_t rowSize = aMatchedFilter.getDimSize(0);
float* fh = nullptr;
cudaMalloc((void**)&fh, sizeof(float) * rowSize * columnSize * Aurora::Complex);
createFhMatrixKernel<<<columnSize, THREADS_PER_BLOCK>>>(aMatchedFilter.getData(), aChannelListBlock.getData(), fh, rowSize);
cudaDeviceSynchronize();
return Aurora::CudaMatrix::fromRawData(fh, rowSize, columnSize, 1, Aurora::Complex);
}

View File

@@ -0,0 +1,10 @@
#ifndef GETTRANSMISSIONDATA_CU_H
#define GETTRANSMISSIONDATA_CU_H
#include "CudaMatrix.h"
Aurora::CudaMatrix getTransmissionDataSubFunction(const Aurora::CudaMatrix& aFxMatrix, const Aurora::CudaMatrix& aFhMatrix);
Aurora::CudaMatrix createFhMatrix(const Aurora::CudaMatrix& aMatchedFilter, const Aurora::CudaMatrix& aChannelListBlock);
#endif

View File

@@ -15,7 +15,12 @@
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <thread>
#include <future>
using namespace Aurora; using namespace Aurora;
using solveParameterIteratorFunctionType = std::vector<std::vector<Aurora::Matrix>> (*)(Aurora::Sparse M, Aurora::Matrix &b,
const Aurora::Matrix &dims, bool oneIter, bool nonNeg, int aDevice);
using slownessToSOSFunctionType = Matrix (*)(Aurora::Matrix & aVF1, float aSOS_IN_WATER);
namespace Recon { namespace Recon {
Aurora::Matrix calculateMinimalMaximalTransducerPositions( Aurora::Matrix calculateMinimalMaximalTransducerPositions(
const Aurora::Matrix &aMSenderList, const Aurora::Matrix &aMReceiverList) { const Aurora::Matrix &aMSenderList, const Aurora::Matrix &aMReceiverList) {
@@ -189,6 +194,7 @@ namespace Recon {
BuildMatrixResult buildMatrixR; BuildMatrixResult buildMatrixR;
for(int iter=1; iter<=numIter; ++iter) for(int iter=1; iter<=numIter; ++iter)
{ {
//1200ms
buildMatrixR = buildMatrix(senderList, receiverList, res, dims, bentRecon && (iter!=1), potentialMap); buildMatrixR = buildMatrix(senderList, receiverList, res, dims, bentRecon && (iter!=1), potentialMap);
if(!data.isNull() && bentRecon && iter != numIter) if(!data.isNull() && bentRecon && iter != numIter)
{ {
@@ -223,17 +229,51 @@ namespace Recon {
allHitMaps.push_back(buildMatrixR.hitmap); allHitMaps.push_back(buildMatrixR.hitmap);
} }
std::promise<Matrix> sosPromise;
std::future<Matrix> sosFuture = sosPromise.get_future();
std::promise<Matrix> attPromise;
std::future<Matrix> attFuture = attPromise.get_future();
solveParameterIteratorFunctionType solveParameterIteratorFunctionPointer = &solveParameterIterator;
slownessToSOSFunctionType slownessToSOSFunctionPointer = &slownessToSOS;
std::thread sosThread;
std::thread attThread;
if(!data.isNull()) if(!data.isNull())
{ {
Matrix sosValue = solveParameterIterator(buildMatrixR.M, b, dims, false, transParams::nonNeg)[0][0]; //1500ms
result.outSOS = slownessToSOS(sosValue, SOS_IN_WATER) ; sosThread = std::thread([solveParameterIteratorFunctionPointer, slownessToSOSFunctionPointer, &buildMatrixR, &b, &dims, &SOS_IN_WATER, &sosPromise]()
{
//auto bCopy = b.deepCopy();
//auto dimCopy = dims.deepCopy();
Matrix result = solveParameterIteratorFunctionPointer(buildMatrixR.M, b, dims, false, transParams::nonNeg, 0)[0][0];
result = slownessToSOSFunctionPointer(result, SOS_IN_WATER);
sosPromise.set_value(result);
});
//Matrix sosValue = solveParameterIterator(buildMatrixR.M, b, dims, false, transParams::nonNeg)[0][0];
//1ms
//result.outSOS = slownessToSOS(sosValue, SOS_IN_WATER) ;
} }
if(!dataAtt.isNull()) if(!dataAtt.isNull())
{ {
Matrix attValue = solveParameterIterator(buildMatrixR.M, bAtt, dims, false, transParams::nonNeg)[0][0]; attThread = std::thread([solveParameterIteratorFunctionPointer, slownessToSOSFunctionPointer, &buildMatrixR, &bAtt, &dims, &attPromise]()
result.outATT = attValue/100 ; {
//auto bAttCopy = bAtt.deepCopy();
//auto dimCopy = dims.deepCopy();
Matrix result = solveParameterIteratorFunctionPointer(buildMatrixR.M, bAtt, dims, false, transParams::nonNeg, 1)[0][0];
result = result / 100;
attPromise.set_value(result);
});
//1500ms
//Matrix attValue = solveParameterIterator(buildMatrixR.M, bAtt, dims, false, transParams::nonNeg)[0][0];
//1ms
//result.outATT = attValue/100 ;
} }
sosThread.join();
attThread.join();
result.outSOS = sosFuture.get();
result.outATT = attFuture.get();
Recon::notifyProgress(10 + 10 * (iter/numIter)); Recon::notifyProgress(10 + 10 * (iter/numIter));
} }

View File

@@ -21,7 +21,7 @@ namespace Recon
bool nonNeg = false; bool nonNeg = false;
}; };
Aurora::Matrix solve( Aurora::Sparse& M, Aurora::Matrix& b, const Aurora::Matrix& dims, int niter, TVAL3SolverOptions solverOptions){ Aurora::Matrix solve( Aurora::Sparse& M, Aurora::Matrix& b, const Aurora::Matrix& dims, int niter, TVAL3SolverOptions solverOptions, int aDevice){
if (Recon::transParams::name.empty()){ if (Recon::transParams::name.empty()){
Recon::transParams::name = "TVAL3"; Recon::transParams::name = "TVAL3";
} }
@@ -39,7 +39,7 @@ namespace Recon
opt.mu = solverOptions.TVAL3MU; opt.mu = solverOptions.TVAL3MU;
opt.beta = solverOptions.TVAL3Beta; opt.beta = solverOptions.TVAL3Beta;
opt.beta0 = solverOptions.TVAL3Beta0; opt.beta0 = solverOptions.TVAL3Beta0;
int device = (int)solverOptions.gpuSelectionList[0]; int device = aDevice;
return callTval3(M, b, dims, device, opt); return callTval3(M, b, dims, device, opt);
} }
//SART //SART
@@ -50,7 +50,7 @@ namespace Recon
} }
std::vector<std::vector<Aurora::Matrix>> solveParameterIterator(Aurora::Sparse M, Aurora::Matrix &b, std::vector<std::vector<Aurora::Matrix>> solveParameterIterator(Aurora::Sparse M, Aurora::Matrix &b,
const Aurora::Matrix &dims, bool oneIter, bool nonNeg) const Aurora::Matrix &dims, bool oneIter, bool nonNeg, int aDevice)
{ {
if (Recon::transParams::name == "TVAL3"){ if (Recon::transParams::name == "TVAL3"){
std::vector<std::vector<Aurora::Matrix>> result(Recon::transParams::muValues.getDataSize()); std::vector<std::vector<Aurora::Matrix>> result(Recon::transParams::muValues.getDataSize());
@@ -82,7 +82,7 @@ namespace Recon
options.TVAL3Beta = Recon::transParams::betaValues[i]; options.TVAL3Beta = Recon::transParams::betaValues[i];
options.TVAL3Beta0 = Recon::transParams::betaValues[i]; options.TVAL3Beta0 = Recon::transParams::betaValues[i];
options.nonNeg = nonNeg; options.nonNeg = nonNeg;
solveResult[j] = solve(M, b, dims, transParams::maxIter, options); solveResult[j] = solve(M, b, dims, transParams::maxIter, options, aDevice);
solveResult[j].forceReshape(dims[0], dims[1], dims.getDataSize()<3?1:dims[2]); solveResult[j].forceReshape(dims[0], dims[1], dims.getDataSize()<3?1:dims[2]);
} }
result[i] = solveResult; result[i] = solveResult;

View File

@@ -6,7 +6,7 @@
namespace Recon { namespace Recon {
std::vector<std::vector<Aurora::Matrix>> std::vector<std::vector<Aurora::Matrix>>
solveParameterIterator(Aurora::Sparse M, Aurora::Matrix &b, solveParameterIterator(Aurora::Sparse M, Aurora::Matrix &b,
const Aurora::Matrix &dims, bool oneIter = true, bool nonNeg = false); const Aurora::Matrix &dims, bool oneIter = true, bool nonNeg = false, int aDevice = 0);
} // namespace Recon } // namespace Recon
#endif // __SOLVE_H__ #endif // __SOLVE_H__

View File

@@ -1,6 +1,7 @@
#include "startTransmissionReconstruction.h" #include "startTransmissionReconstruction.h"
#include "./detection/getTransmissionData.h" #include "./detection/getTransmissionData.h"
#include "Matrix.h" #include "Matrix.h"
#include "CudaMatrix.h"
#include "log/log.h" #include "log/log.h"
#include "common/dataBlockCreation/removeDataFromArrays.h" #include "common/dataBlockCreation/removeDataFromArrays.h"
#include "log/notify.h" #include "log/notify.h"
@@ -29,22 +30,22 @@ TransmissionReconstructionResult Recon::startTransmissionReconstruction(const Au
aGeom, aGeomRef, aExpInfo, aExpInfoRef, aPreComputes, aParser, aParserRef); aGeom, aGeomRef, aExpInfo, aExpInfoRef, aPreComputes, aParser, aParserRef);
Matrix dists = Recon::distanceBetweenTwoPoints(transmissionData.senderList, transmissionData.receiverList); Matrix dists = Recon::distanceBetweenTwoPoints(transmissionData.senderList, transmissionData.receiverList);
Matrix sosRef = Recon::temperatureToSoundSpeed(transmissionData.waterTempList, "marczak"); Matrix sosRef = Recon::temperatureToSoundSpeed(transmissionData.waterTempList, "marczak");
Recon::notifyProgress(17); //Recon::notifyProgress(17);
Matrix valid = Recon::checkTofDetections(transmissionData.tofDataTotal, dists, sosRef, Matrix valid = Recon::checkTofDetections(transmissionData.tofDataTotal, dists, sosRef,
Recon::transParams::minSpeedOfSound,Recon::transParams::maxSpeedOfSound).valid; Recon::transParams::minSpeedOfSound,Recon::transParams::maxSpeedOfSound).valid;
Recon::notifyProgress(18); //Recon::notifyProgress(18);
if(transParams::qualityCheck) if(transParams::qualityCheck)
{ {
qualityReview(sum(valid,Aurora::All)[0], transmissionData.dataInfo.numPossibleScans); qualityReview(sum(valid,Aurora::All)[0], transmissionData.dataInfo.numPossibleScans);
} }
Recon::notifyProgress(19); //Recon::notifyProgress(19);
DiscretizePositionValues positionValues = Recon::discretizePositions(transmissionData.senderList, transmissionData.receiverList, Recon::transParams::numPixelXY); DiscretizePositionValues positionValues = Recon::discretizePositions(transmissionData.senderList, transmissionData.receiverList, Recon::transParams::numPixelXY);
Matrix tofData = removeDataFromArrays(transmissionData.tofDataTotal, valid); Matrix tofData = removeDataFromArrays(transmissionData.tofDataTotal, valid);
Matrix attData = removeDataFromArrays(transmissionData.attDataTotal, valid); Matrix attData = removeDataFromArrays(transmissionData.attDataTotal, valid);
Matrix senderList = removeDataFromArrays(positionValues.senderCoordList, valid); Matrix senderList = removeDataFromArrays(positionValues.senderCoordList, valid);
Matrix reveiverList = removeDataFromArrays(positionValues.receiverCoordList, valid); Matrix reveiverList = removeDataFromArrays(positionValues.receiverCoordList, valid);
Recon::notifyProgress(20); //Recon::notifyProgress(20);
RECON_INFO("Start reconstructArt."); RECON_INFO("Start reconstructArt.");
auto transmissionReon = reconstructArt(tofData, attData, positionValues.dims, senderList, reveiverList, positionValues.res, aTemp.expectedSOSWater[0]); auto transmissionReon = reconstructArt(tofData, attData, positionValues.dims, senderList, reveiverList, positionValues.res, aTemp.expectedSOSWater[0]);