Skip to content

Commit 27d6f49

Browse files
Merge pull request #85 from PauloCarvalhoRJ/FFT2D
Fft2d
2 parents b3dca34 + bda052c commit 27d6f49

13 files changed

+658
-17
lines changed

GammaRay.pro

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ SOURCES += main.cpp\
142142
viewer3d/view3dlistrecord.cpp \
143143
viewer3d/view3dviewdata.cpp \
144144
viewer3d/view3dconfigwidgets/v3dcfgwidforattributeinmapcartesiangrid.cpp \
145-
domain/auxiliary/dataloader.cpp
145+
domain/auxiliary/dataloader.cpp \
146+
array3d.cpp
146147

147148
HEADERS += mainwindow.h \
148149
domain/project.h \
@@ -266,7 +267,8 @@ HEADERS += mainwindow.h \
266267
viewer3d/view3dlistrecord.h \
267268
viewer3d/view3dviewdata.h \
268269
viewer3d/view3dconfigwidgets/v3dcfgwidforattributeinmapcartesiangrid.h \
269-
domain/auxiliary/dataloader.h
270+
domain/auxiliary/dataloader.h \
271+
array3d.h
270272

271273
FORMS += mainwindow.ui \
272274
gslib/gslibparams/widgets/widgetgslibpardouble.ui \
@@ -362,12 +364,13 @@ LIBS += -lvtkGUISupportQt$$VTK_VERSION_SUFFIX \
362364
-lvtkImagingSources$$VTK_VERSION_SUFFIX \
363365
-lvtkImagingCore$$VTK_VERSION_SUFFIX \
364366
-lvtkFiltersCore$$VTK_VERSION_SUFFIX \
365-
-lvtkFiltersExtraction$$VTK_VERSION_SUFFIX
367+
-lvtkFiltersExtraction$$VTK_VERSION_SUFFIX \
368+
-lvtkImagingFourier$$VTK_VERSION_SUFFIX
366369

367370
# The application version
368371
# Don't forget to update the Util::importSettingsFromPreviousVersion() method to
369372
# enable the import of registry/user settings of previous versions.
370-
VERSION = 2.1
373+
VERSION = 2.2
371374

372375
# Define a preprocessor macro so we can get the application version in application code.
373376
DEFINES += APP_VERSION=\\\"$$VERSION\\\"

array3d.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "array3d.h"
2+
3+

array3d.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifndef ARRAY3D_H
2+
#define ARRAY3D_H
3+
4+
#include <vector>
5+
#include <cstdlib>
6+
#include <stdexcept>
7+
8+
/**
9+
* The Array3D class is a generic array of any object type with rank 3 (3 dimensions, IJK).
10+
* It wraps an unidimensional array, hiding index arithmetic, allowing a more readable code (e.g. a(i,j,k))
11+
* while preserving memory locality, leading to better performance (e.g. more cache hits), since multidimensional
12+
* arrays tend to scatter in memory.
13+
* The Array3D can be used as a two-dimensional array in code (e.g. a(i,j) assumes k = 0)
14+
*/
15+
template <class TYPE>
16+
class Array3D
17+
{
18+
public:
19+
Array3D(size_t nI, size_t nJ, size_t nK = 1):
20+
_nI(nI), _nJ(nJ), _nK(nK), _vec( nI * nJ * nK )
21+
{}
22+
23+
TYPE & operator()( size_t i, size_t j, size_t k = 0 ) {
24+
if ( i < _nI && j < _nJ && k < _nK ) {
25+
return _vec[ i + j * _nI + k * _nJ * _nI ];
26+
}
27+
throw std::out_of_range("Indexes out of range");
28+
}
29+
30+
TYPE operator()( size_t i, size_t j, size_t k = 0 ) const {
31+
if ( i < _nI && j < _nJ && k < _nK ) {
32+
return _vec[ i + j * _nI + k * _nJ * _nI ];
33+
}
34+
throw std::out_of_range("Indexes out of range");
35+
}
36+
37+
private:
38+
size_t _nI;
39+
size_t _nJ;
40+
size_t _nK;
41+
std::vector<TYPE> _vec;
42+
};
43+
#endif // ARRAY3D_H

docs/GammaRayManual.docx

375 KB
Binary file not shown.

domain/cartesiangrid.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,31 @@ void CartesianGrid::setInfoFromGridParameter(GSLibParGrid *pg)
180180
this->setInfo( x0, y0, z0, dx, dy, dz, nx, ny, nz, rot, nreal, ndv, empty, empty2);
181181
}
182182

183+
double CartesianGrid::dataIJK(uint column, uint i, uint j, uint k)
184+
{
185+
uint dataRow = i + j*_nx + k*_ny*_nx;
186+
return data( dataRow, column );
187+
}
188+
189+
std::vector<std::complex<double> > CartesianGrid::getArray(int indexColumRealPart, int indexColumImaginaryPart)
190+
{
191+
std::vector< std::complex<double> > result( _nx * _ny * _nz ); //[_nx][_ny][_nz]
192+
193+
for( uint k = 0; k < _nz; ++k)
194+
for( uint j = 0; j < _ny; ++j)
195+
for( uint i = 0; i < _nx; ++i){
196+
double real = 0.0d;
197+
double im = 0.0d;
198+
if( indexColumRealPart >= 0 )
199+
real = dataIJK( indexColumRealPart, i, j, k);
200+
if( indexColumImaginaryPart >= 0 )
201+
im = dataIJK( indexColumImaginaryPart, i, j, k);
202+
result[i + j*_nx + k*_ny*_nx] = std::complex<double>(real, im);
203+
}
204+
205+
return result;
206+
}
207+
183208
bool CartesianGrid::canHaveMetaData()
184209
{
185210
return true;

domain/cartesiangrid.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define CARTESIANGRID_H
33

44
#include "datafile.h"
5+
#include <complex>
56

67
class GSLibParGrid;
78

@@ -55,6 +56,23 @@ class CartesianGrid : public DataFile
5556
uint getNReal(){ return _nreal; }
5657
//@}
5758

59+
/**
60+
* Returns a value from the data column (0 = 1st column) given a grid topological coordinate (IJK).
61+
* @param i must be between 0 and NX-1.
62+
* @param j must be between 0 and NY-1.
63+
* @param k must be between 0 and NZ-1.
64+
*/
65+
double dataIJK(uint column, uint i, uint j, uint k);
66+
67+
/** Creates a vector of complex numbers with the values taken from data columns.
68+
* Specify -1 to omit a column, which causes the repective part to be filled with zeros.
69+
* getArray(-1,-1) returns an array filled with zeroes. The dimension of the array is that
70+
* of the Cartesian grid (getNX(), getNY(), getNZ()).
71+
* @param indexColumRealPart Column index (starting with 0) with the values for the real part.
72+
* @param indexColumRealPart Column index (starting with 0) with the values for the imaginary part.
73+
*/
74+
std::vector< std::complex<double> > getArray( int indexColumRealPart, int indexColumImaginaryPart = -1 );
75+
5876
//DataFile interface
5977
public:
6078
/** Cartesian grids never have declustering weights. At least they are not supposed to be. */

mainwindow.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ MainWindow::MainWindow(QWidget *parent) :
137137
setAcceptDrops( true );
138138

139139
//show the 3D view widget
140-
ui->frmContent->layout()->addWidget( new View3DWidget() );
140+
ui->frmContent->layout()->addWidget( new View3DWidget( this ) );
141141
}
142142

143143
MainWindow::~MainWindow()
@@ -449,6 +449,9 @@ void MainWindow::onProjectContextMenu(const QPoint &mouse_location)
449449
_projectContextMenu->addMenu( m_subMenuClassifyWith );
450450
_projectContextMenu->addAction("Soft indicator calibration...", this, SLOT(onSoftIndicatorCalib()) );
451451
}
452+
if( parent_file->getFileType() == "CARTESIANGRID" ){
453+
_projectContextMenu->addAction("FFT", this, SLOT(onFFT()));
454+
}
452455
}
453456
//two items were selected. The context menu depends on the combination of items.
454457
} else if ( selected_indexes.size() == 2 ) {
@@ -1293,6 +1296,53 @@ void MainWindow::onFreeLoadedData()
12931296
Application::instance()->getProject()->freeLoadedData();
12941297
}
12951298

1299+
void MainWindow::onFFT()
1300+
{
1301+
//propose a name for the new grid to contain the FFT image
1302+
QString proposed_name = _right_clicked_attribute->getName() + "_FFT.dat";
1303+
1304+
//user enters the name for the new grid with FFT image
1305+
QString new_cg_name = QInputDialog::getText(this, "Name the new grid",
1306+
"Name for the grid with FFT image:", QLineEdit::Normal,
1307+
proposed_name );
1308+
1309+
//if the user canceled the input box
1310+
if ( new_cg_name.isEmpty() ){
1311+
//abort
1312+
return;
1313+
}
1314+
1315+
//the parent file is surely a CartesianGrid.
1316+
CartesianGrid *cg = (CartesianGrid*)_right_clicked_attribute->getContainingFile();
1317+
1318+
//get the array containing the data
1319+
std::vector< std::complex<double> > array = cg->getArray( _right_clicked_attribute->getAttributeGEOEASgivenIndex()-1 );
1320+
1321+
//run FFT
1322+
Util::fft3D( cg->getNX(),
1323+
cg->getNY(),
1324+
cg->getNZ(),
1325+
array,
1326+
FFTComputationMode::DIRECT);
1327+
1328+
//make a tmp file path
1329+
QString tmp_file_path = Application::instance()->getProject()->generateUniqueTmpFilePath("dat");
1330+
1331+
//crate a new cartesian grid pointing to the tmp path
1332+
CartesianGrid * new_cg = new CartesianGrid( tmp_file_path );
1333+
1334+
//set the geometry info based on the original grid
1335+
new_cg->setInfoFromOtherCG( cg, false );
1336+
1337+
//save the results in the project's tmp directory
1338+
Util::createGEOEASGrid( "Real part", "Imaginary part", array, tmp_file_path);
1339+
1340+
//import the saved file to the project
1341+
Application::instance()->getProject()->importCartesianGrid( new_cg, new_cg_name );
1342+
1343+
Application::instance()->logInfo("FFT 2D completed.");
1344+
}
1345+
12961346
void MainWindow::onCreateCategoryDefinition()
12971347
{
12981348
CategoryDefinition *cd = new CategoryDefinition("");

mainwindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ private slots:
143143
void onMapAs();
144144
void onSoftIndicatorCalib();
145145
void onFreeLoadedData();
146+
void onFFT();
146147

147148
private:
148149
/**

0 commit comments

Comments
 (0)