void test() {
    using namespace vigra;
    typedef Thresholding<3, float>::V V;

    MultiArray<3, float> data(V(24,33,40));
    FillRandom<float, float*>::fillRandom(data.data(), data.data()+data.size());
    {
        HDF5File f("test.h5", HDF5File::Open);
        f.write("test", data);
    }

    SourceHDF5<3, float> source("test.h5", "test");
    SinkHDF5<3, vigra::UInt8> sink("thresh.h5", "thresh");
    sink.setBlockShape(V(10,10,10));

    Thresholding<3, float> bs(&source, V(6,4,7));

    bs.run(0.5, 0, 1, &sink);

    HDF5File f("thresh.h5", HDF5File::Open);
    MultiArray<3, UInt8> r;
    f.readAndResize("thresh", r);

    MultiArray<3, UInt8> t(data.shape());
    transformMultiArray(srcMultiArrayRange(data), destMultiArray(t), Threshold<float, UInt8>(-std::numeric_limits<float>::max(), 0.5, 1, 0));
    shouldEqual(t.shape(), r.shape());
    shouldEqualSequence(r.begin(), r.end(), t.begin());
}
void testRoi() {
    using namespace vigra;
    typedef ChannelSelector<4, float>::V V;
    typedef vigra::TinyVector<int, 4> V4;
    
    int ch = 0;
   
    MultiArray<4, float> data(vigra::TinyVector<int, 4>(10,20,30,2));
    FillRandom<float, float*>::fillRandom(data.data(), data.data()+data.size());
    {
        HDF5File f("test.h5", HDF5File::Open);
        f.write("test", data);
    }
    
    SourceHDF5<4, float> source("test.h5", "test");
    source.setRoi(Roi<4>(V4(1,3,5,0), V4(7,9,30,2)));
    
    SinkHDF5<3, float> sink("channel.h5", "channel");
    
    ChannelSelector<4, float> cs(&source, V(10,10,10));
    
    cs.run(3, ch, &sink);

    HDF5File f("channel.h5", HDF5File::Open);
    MultiArray<3, float> r;
    f.readAndResize("channel", r);

    MultiArrayView<3, float> shouldResult = data.bind<3>(ch).subarray(V(1,3,5), V(7,9,30));
    
    shouldEqualSequence(r.begin(), r.end(), shouldResult.begin());
}
void test() {
    using namespace vigra;
    typedef ChannelSelector<4, float>::V V;
   
    for(int ch=0; ch<=1; ++ch) {
        std::cout << "* channel = " << ch << std::endl;
    
        MultiArray<4, float> data(vigra::TinyVector<int, 4>(10,20,30,2));
        FillRandom<float, float*>::fillRandom(data.data(), data.data()+data.size());
        {
            HDF5File f("test.h5", HDF5File::Open);
            f.write("test", data);
        }
        
        SourceHDF5<4, float> source("test.h5", "test");
        SinkHDF5<3, float> sink("channel.h5", "channel");
        sink.setBlockShape(V(10,10,10));
        
        ChannelSelector<4, float> cs(&source, V(10,10,10));
        
        cs.run(3, ch, &sink);
    
        HDF5File f("channel.h5", HDF5File::Open);
        MultiArray<3, float> r;
        f.readAndResize("channel", r);
    
        MultiArrayView<3, float> shouldResult = data.bind<3>(ch);
        
        shouldEqualSequence(r.begin(), r.end(), shouldResult.begin());
    } //loop through channels
}
Example #4
0
void ApplyFilter3D(MultiArray<complex<float>, 3> ks, MultiArray<float, 3> filter) {
    if ((ks.dims() != filter.dims()).any()) {
        throw(runtime_error("K-space and filter dimensions do not match."));
    }

    auto k_it = ks.begin();
    auto f_it = filter.begin();
    while (k_it != ks.end()) {
        *k_it = (*k_it) * (*f_it);
        k_it++;
        f_it++;
    }
}
Example #5
0
int main(int argc, char **argv) {
    int indexptr = 0, c;
    string outPrefix = "";
    bool zip = false, kspace = false, procpar = false;
    Filters filterType = Filters::None;
    float f_a = 0, f_q = 0;
    Nifti::DataType dtype = Nifti::DataType::COMPLEX64;
    Affine3f scale; scale = Scaling(1.f);

    while ((c = getopt_long(argc, argv, short_options, long_options, &indexptr)) != -1) {
        switch (c) {
        case 0: break; // It was an option that just sets a flag.
        case 'o': outPrefix = string(optarg); break;
        case 'z': zip = true; break;
        case 'k': kspace = true; break;
        case 'm': dtype = Nifti::DataType::FLOAT32; break;
        case 's': scale = Scaling(static_cast<float>(atof(optarg))); break;
        case 'f':
            switch (*optarg) {
            case 'h':
                filterType = Filters::Hanning;
                f_a = 0.1;
                break;
            case 't':
                filterType = Filters::Tukey;
                f_a = 0.75;
                f_q = 0.25;
                break;
            default:
                cerr << "Unknown filter type: " << string(optarg, 1) << endl;
                return EXIT_FAILURE;
            }
            break;
        case 'a':
            if (filterType == Filters::None) {
                cerr << "No filter type specified, so f_a is invalid" << endl;
                return EXIT_FAILURE;
            }
            f_a = atof(optarg);
            break;
        case 'q':
            if (filterType != Filters::Tukey) {
                cerr << "Filter type is not Tukey, f_q is invalid" << endl;
                return EXIT_FAILURE;
            }
            f_q = atof(optarg);
            break;
        case 'p': procpar = true; break;
        case 'v': verbose = true; break;
        case '?': // getopt will print an error message
            cout << usage << endl;
            return EXIT_FAILURE;
        default:
            cout << "Unhandled option " << string(1, c) << endl;
            return EXIT_FAILURE;
        }
    }

    if ((argc - optind) <= 0) {
        cout << usage << endl;
        cout << "No .fids specified" << endl;
        return EXIT_FAILURE;
    }

    while (optind < argc) {
        string inPath(argv[optind++]);
        size_t fileSep = inPath.find_last_of("/") + 1;
        size_t fileExt = inPath.find_last_of(".");
        if ((fileExt == string::npos) || (inPath.substr(fileExt) != ".fid")) {
            cerr << inPath << " is not a valid .fid directory" << endl;
        }
        string outPath = outPrefix + inPath.substr(fileSep, fileExt - fileSep) + ".nii";
        if (zip)
            outPath = outPath + ".gz";

        Agilent::FID fid(inPath);


        string apptype = fid.procpar().stringValue("apptype");
        string seqfil  = fid.procpar().stringValue("seqfil");

        if (apptype != "im3D") {
            cerr << "apptype " << apptype << " not supported, skipping." << endl;
            continue;
        }

        if (verbose) {
            cout << fid.print_info() << endl;
            cout << "apptype = " << apptype << endl;
            cout << "seqfil  = " << seqfil << endl;
        }

        /*
         * Assemble k-Space
         */
        MultiArray<complex<float>, 4> vols;
        if (seqfil.substr(0, 5) == "mge3d") {
            vols = reconMGE(fid);
        } else if (seqfil.substr(0, 7) == "mp3rage") {
            vols = reconMP2RAGE(fid);
        } else {
            cerr << "Recon for " << seqfil << " not implemented, skipping." << endl;
            continue;
        }

        /*
         * Build and apply filter
         */
        MultiArray<float, 3> filter;
        switch (filterType) {
        case Filters::None: break;
        case Filters::Hanning:
            if (verbose) cout << "Building Hanning filter" << endl;
            filter = Hanning3D(vols.dims().head(3), f_a);
            break;
        case Filters::Tukey:
            if (verbose) cout << "Building Tukey filter" << endl;
            filter = Tukey3D(vols.dims().head(3), f_a, f_q);
            break;
        }
        if (filterType != Filters::None) {
            if (verbose) cout << "Applying filter" << endl;
            for (int v = 0; v < vols.dims()[3]; v++) {
                MultiArray<complex<float>, 3> vol = vols.slice<3>({0,0,0,v},{-1,-1,-1,0});
                ApplyFilter3D(vol,filter);
            }
        }
        /*
         * FFT
         */
        if (!kspace) {
            for (int v = 0; v < vols.dims()[3]; v++) {
                if (verbose) cout << "FFTing vol " << v << endl;
                MultiArray<complex<float>, 3> vol = vols.slice<3>({0,0,0,v},{-1,-1,-1,0});
                phase_correct_3(vol, fid);
                fft_shift_3(vol);
                fft_X(vol);
                fft_Y(vol);
                fft_Z(vol);
                fft_shift_3(vol);
            }
        }

        if (verbose) cout << "Writing file: " << outPath << endl;
        list<Nifti::Extension> exts;
        if (procpar) {
            if (verbose) cout << "Embedding procpar" << endl;
            ifstream pp_file(inPath + "/procpar", ios::binary);
            pp_file.seekg(ios::end);
            size_t fileSize = pp_file.tellg();
            pp_file.seekg(ios::beg);
            vector<char> data; data.reserve(fileSize);
            data.assign(istreambuf_iterator<char>(pp_file), istreambuf_iterator<char>());
            exts.emplace_back(NIFTI_ECODE_COMMENT, data);
        }
        Affine3f xform  = scale * fid.procpar().calcTransform();
        ArrayXf voxdims = (Affine3f(xform.rotation()).inverse() * xform).matrix().diagonal();
        Nifti::Header outHdr(vols.dims(), voxdims, dtype);
        outHdr.setTransform(xform);
        Nifti::File output(outHdr, outPath, exts);
        output.writeVolumes(vols.begin(), vols.end(), 0, vols.dims()[3]);
        output.close();
    }
    return 0;
}