FFT node - problem calling algorithm

Hi, I was writing a node that would perform a Fourier Transform, and I'm having some trouble with calling the algorithm itself. The way I have it set up is with a fft method created that takes in a complex array of numbers, does the transform, and outputs a complex array. The problem is, in the execute method, I'd be passing in a table of complex numbers, but I don't know how to extract those complex numbers from the table. I see that the execute method takes in a BufferedDataTable, and I've searched through the API for that, along with the API for a DataTableSpec and DataColumnSpec. I see how to compare types, but I'm not sure how to actually extract the complex numbers from the table. Any help would be greatly appreciated, thank you very much.

Hi, to access the data (DataCells) in the BufferedDataTable, you need to iterator over the table. The iterator returns DataRow objects which then contain DataCells of a particular type. Note, you can figure out the type before by parsing the DataTableSpec:

        DataTableSpec spec = ...
        for (int i = 0; i < spec.getNumColumns(); i++) {
            DataColumnSpec cspec = spec.getColumnSpec(i);
            DataType type = cspec.getType();
            if (type.isCompatible(ComplexNumberValue.class)) {
               ...
            }
        } 

Now, where you figured out which columns are of type ComplexNumberValue, you can easily cast each object to ComplexNumberValue and access the real and imaginary part. In a last step you need to write these values into your own data structure and call your FF algorithm.
        BufferedDataTable data = ...
        for (DataRow row : data) {
            for (DataCell cell : row) {
                // handle missing values
                if (!cell.isMissing()) {
                  // we assume all columns are of type ComplexNumberValue
                  // but you will need to check this before
                  ComplexNumberValue value = (ComplexNumberValue) cell;
                  double real = value();
                  double imag = value.getImaginaryValue();
                  // store real and imag into your data structure
               } else {
                  ...
               }
            }
        }

Gabriel, thank you so much for your help, I knew it had something to do with DataRow and DataCell but I wasn't quite sure how to use it. That code was extremely helpful. I'm really sorry to ask for more help, but I almost have it working, I'm just having the problem of loading the information back into a BufferedDataTable. I tried just loading the information back into the cells that I had from the input data table, but all I ended up doing was loading the information into a local variable, rather then actually loading it back into the table itself and returning that. So, basically, the program ended up returning the table that was input (not all that helpful). I've been looking for some kind of load method, but haven't found one yet; does anyone know of anything like this? Any help would be greatly appreciated, thank you!

-James

[...] ok, some more coding :-) In order to write (new) data to the node's output, you need to create a BufferedDataContainer to which you can add rows containing DataCell objects (the actual data). A first step is to create the names and types of the output table using the DataColumnSpecCreater which generates DataColumnSpec objects which are then used to initialize a DataTableSpec. The attached example shows how to write an array of doubles to the output. Please feel free to adapt this code snippet to fit your needs:

   BufferedDataTable[] execute(...) {
        // contains the result of the FF algorithm
        double[][] data = ...
        // create column names and types of the output table
        DataColumnSpec[] cspec = new DataColumnSpec[data.length];
        for (int i = 0; i < cspec.length; i++) {
            cspec[i] = new DataColumnSpecCreator(
                    "Col" + i, DoubleCell.TYPE).createSpec();
        }
        DataTableSpec spec = new DataTableSpec(cspec);
        // write DataRow objects into this container
        BufferedDataContainer buf = exec.createDataContainer(spec);
        if (data.length > 0) {
            for (int i = 0; i < data[0].length; i++) {
                DataCell[] cells = new DataCell[data.length];
                for (int j = 0; j < cells.length; j++) {
                    cells[j] = new DoubleCell(data[j][i]);
                }
                // generate a new row key or use the one from the input data
                DataCell rowKey = new StringCell("Row" + i);
                // add each row to the buffer
                buf.addRowToTable(new DefaultRow(rowKey, cells));
            }
        }
        buf.close();
        return new BufferedDataTable[]{buf.getTable()};
   }

Gabriel, thank you so much for your help, it would have taken me forever without all that! I really appreciate all that code, thank you!