Пример #1
0
voreen::VolumeCollection* VolumeCollection::selectOrigin(const VolumeOrigin& origin) const {
    VolumeCollection* collection = new VolumeCollection();
    for (size_t i=0; i<volumeHandles_.size(); ++i) {
        if (volumeHandles_[i]->getOrigin() == origin)
            collection->add(volumeHandles_[i]);
    }
    return collection;
}
Пример #2
0
VolumeCollection* VolumeCollection::subCollection(const std::vector<size_t>& indices) const {
    VolumeCollection* subCollection = new VolumeCollection();
    for (size_t i=0; i<indices.size(); i++) {
        tgtAssert(indices.at(i) < volumeHandles_.size(), "invalid index");
        subCollection->add(volumeHandles_.at(indices.at(i)));
    }
    return subCollection;
}
Пример #3
0
VolumeCollection* VolumeCollection::selectModality(const Modality& modality) const {

    VolumeCollection* collection = new VolumeCollection();
    for (size_t i=0; i<volumeHandles_.size(); ++i) {
        if (volumeHandles_[i]->getModality() == modality)
            collection->add(volumeHandles_[i]);
    }
    return collection;
}
Пример #4
0
voreen::VolumeCollection* VolumeCollection::selectOrigin(const VolumeURL& origin) const {
    VolumeCollection* collection = new VolumeCollection();
    for (size_t i=0; i<volumeHandles_.size(); ++i) {
        Volume* vh = dynamic_cast<Volume*>(volumeHandles_[i]);
        if (vh && vh->getOrigin() == origin)
            collection->add(volumeHandles_[i]);
    }
    return collection;
}
Пример #5
0
VolumeCollection* VolumeCollection::subCollection(size_t start, size_t end) const {
    VolumeCollection* subCollection = new VolumeCollection();
    tgtAssert(start <= end, "invalid indices");
    tgtAssert(start < volumeHandles_.size(), "invalid start index");
    tgtAssert(end < volumeHandles_.size(), "invalid end index");
    for (size_t index = start; index <= end; index++)
        subCollection->add(volumeHandles_.at(index));
    return subCollection;
}
Пример #6
0
VolumeCollection* VolumeCollection::selectTimestep(float timestep) const {

    VolumeCollection* collection = new VolumeCollection();
    for (size_t i=0; i<volumeHandles_.size(); ++i) {
        if (volumeHandles_[i]->getTimestep() == timestep)
            collection->add(volumeHandles_[i]);
    }
    return collection;
}
Пример #7
0
voreen::VolumeCollection* VolumeCollection::selectOriginTimestep(const VolumeOrigin& origin, float timestep) const {
    VolumeCollection* collection = new VolumeCollection();
    for (size_t i=0; i<volumeHandles_.size(); ++i) {
        VolumeHandle* vh = dynamic_cast<VolumeHandle*>(volumeHandles_[i]);
        if (vh && vh->getOrigin() == origin && vh->getTimestep() == timestep)
            collection->add(volumeHandles_[i]);
    }
    return collection;
}
Пример #8
0
VolumeCollection* RawVoxVolumeReader::read(const std::string &url)
throw (tgt::CorruptedFileException, tgt::IOException, std::bad_alloc)
{
    VolumeURL origin(url);
    std::string fileName = origin.getPath();

    LINFO("Reading file " << fileName);

    std::fstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
    if (!fin.good())
        throw tgt::IOException();

    RawVoxHeader header;
    fin.read(reinterpret_cast<char*>(&header), sizeof(header));
    svec3 dimensions = svec3(header.sizeX_, header.sizeY_, header.sizeZ_);

    if(header.magic_ != 1381388120) {
        throw tgt::CorruptedFileException("Wrong magic number.");
    }

    VolumeRAM* dataset;
    switch(header.bitsPerVoxel_) {
    case 8:
        LINFO("Reading 8 bit dataset");
        dataset = new VolumeRAM_UInt8(dimensions);
        break;
    case 16:
        LINFO("Reading 16 bit dataset");
        dataset = new VolumeRAM_UInt16(dimensions);
        break;
    case 32:
        LINFO("Reading 32 bit (float) dataset");
        dataset = new VolumeRAM_Float(dimensions);
        break;
    default:
        LERROR("Unknown bpp!");
        throw tgt::UnsupportedFormatException("Unexpected bpp.");
    }

    fin.read(reinterpret_cast<char*>(dataset->getData()), dataset->getNumBytes());

    if ( fin.eof() ) {
        delete dataset;
        throw tgt::CorruptedFileException();
    }

    fin.close();

    VolumeCollection* volumeCollection = new VolumeCollection();
    Volume* volumeHandle = new Volume(dataset, vec3(1.0f), vec3(0.0f));
    oldVolumePosition(volumeHandle);
    volumeHandle->setOrigin(fileName);
    volumeCollection->add(volumeHandle);

    return volumeCollection;
}
Пример #9
0
VolumeCollection* VvdVolumeReader::read(const std::string &url)
    throw (tgt::FileException, std::bad_alloc)
{
    VolumeURL origin(url);
    std::string fileName = origin.getPath();

    // open file for reading
    std::fstream fileStream(fileName.c_str(), std::ios_base::in);
    if (fileStream.fail()) {
        throw tgt::FileException("Failed to open file '" + tgt::FileSystem::absolutePath(fileName) + "' for reading.");
    }

    // read data stream into deserializer
    XmlDeserializer d(fileName);
    d.setUseAttributes(true);
    try {
        d.read(fileStream);
    }
    catch (SerializationException& e) {
        throw tgt::FileException("SerializationException: Failed to read serialization data stream from file '"
                                     + fileName + "': " + e.what());
    }
    catch (...) {
        throw tgt::FileException("Failed to read serialization data stream from file '"
                                     + fileName + "' (unknown exception).");
    }

    std::vector<VvdObject> vec;
    // deserialize from data stream
    try {
        d.deserialize("Volumes", vec, "Volume");
    }
    catch (std::exception& e) {
        throw tgt::FileException("Deserialization from file '" + fileName + "' failed: " + e.what());
    }
    catch (...) {
        throw tgt::FileException("Deserialization from file '" + fileName + "' failed (unknown exception).");
    }
    if (vec.empty())
        throw tgt::FileException("Deserialization from file '" + fileName + "' failed: no volume found");

    VolumeCollection* vc = new VolumeCollection();
    for(size_t i=0; i<vec.size(); i++) {
        Volume* vh = vec[i].createVolume(tgt::FileSystem::dirName(fileName));
        vh->setOrigin(origin);
        vc->add(vh);
    }

    return vc;
}
Пример #10
0
VolumeCollection* TransFuncListProperty::getVolumes(bool selectedOnly /*= true*/) const {
    VolumeCollection* collection = new VolumeCollection();
    std::vector<std::string> urls = get();
    for (size_t i=0; i<urls.size(); i++) {
        std::string url = urls.at(i);
        if (handleMap_.find(url) != handleMap_.end()) {
            if (!selectedOnly || (selectionMap_.find(url) != selectionMap_.end() && selectionMap_.find(url)->second == true) ) {
                VolumeBase* handle = handleMap_.find(url)->second;
                tgtAssert(handle, "handleMap_ contains null pointer");
                collection->add(handle);
            }
        }
    }

    return collection;
}
Пример #11
0
VolumeBase* AnalyzeVolumeReader::read(const VolumeURL& origin)
    throw (tgt::FileException, std::bad_alloc)
{
    VolumeBase* result = 0;

    int volumeId = -1;
    std::string tmp = origin.getSearchParameter("volumeId");
    if (! tmp.empty())
        volumeId = stoi(tmp);

    VolumeCollection* collection = read(origin.getPath(), volumeId);

    if (collection && collection->size() == 1) {
        result = collection->first();
    }
    else if (collection && collection->size() > 1) {
        while(!collection->empty()) {
           VolumeBase* vh = collection->first();
           collection->remove(vh);
           delete vh;
        }
        delete collection;
        throw tgt::FileException("Only one volume expected", origin.getPath());
    }

    delete collection;

    return result;
}
Пример #12
0
VolumeCollection* MultiVolumeReader::read(const std::string& url)
    throw (tgt::FileException, std::bad_alloc)
{
    LINFO("Loading multi volume file " << url);
    VolumeURL urlOrigin(url);

    std::vector<VolumeURL> origins = listVolumes(url);
    if (origins.empty())
        throw tgt::FileException("No volumes listed in multi-volume file", url);

    VolumeCollection* volumeCollection = new VolumeCollection();

    std::string refFile = urlOrigin.getSearchParameter("file");
    if (refFile == "") {
        // no particular file specified in URL => load all listed ones
        for (size_t i=0; i<origins.size(); i++) {
            VolumeBase* handle = read(origins.at(i));
            if (handle)
                volumeCollection->add(handle);
        }
    }
    else {
        // load specified file
        for (size_t i=0; i<origins.size(); i++) {
            if (origins.at(i).getSearchParameter("file") == refFile) {
                VolumeBase* handle = read(origins.at(i));
                if (handle) {
                    volumeCollection->add(handle);
                    break;
                }
            }
        }

        if (volumeCollection->empty()) {
            delete volumeCollection;
            throw tgt::FileException("File '" + refFile + "' not listed in multi-volume file", urlOrigin.getPath());
        }
    }

    return volumeCollection;
}
void VolumeCollectionModalityFilter::adjustFilteredCollection() {
    VolumeCollection* collection = inport_.getData();
    if ((collection == 0) || (collection->empty() == true)) {
        filteredCollection_.clear();
        outport_.setData(0);
        return;
    }

    if (currentModality_.getName() != modalityProp_.get()) {
        currentModality_ = *(modalityProp_.getValue());
        filteredCollection_.clear();
        if (currentModality_ != Modality::MODALITY_ANY) {
            for (size_t i = 0; i < collection->size(); ++i) {
                if (collection->at(i)->getModality() == currentModality_)
                    filteredCollection_.add(collection->at(i));
            }
            outport_.setData(&filteredCollection_);
        } else
            outport_.setData(inport_.getData());
    }
}
Пример #14
0
VolumeCollection* MRCVolumeReader::read(const std::string &url)
    throw (tgt::FileException, tgt::IOException, std::bad_alloc)
{
    VolumeCollection* volumeCollection = new VolumeCollection();

    VolumeURL origin(url);
    std::string fileName = origin.getPath();
    LINFO(fileName);
    
    std::ifstream mrc;
    mrc.open(fileName.c_str(), std::ios::binary);
    if (!mrc.is_open()) {
        LWARNING("Can't open stream");
    }
    else {
        int dim[3]; // grid dimensions i.e. numbers of voxels for each dimension
        mrc.read((char*)(&dim), sizeof(dim));
        std::cout << "X: " << dim[0] << std::endl; // number of columns (fastest changing in map)
        std::cout << "Y: " << dim[1] << std::endl; // number of rows
        std::cout << "Z: " << dim[2] << std::endl; // number of sections (slowest changing in map)
        
        int numVoxels = dim[0] * dim[1] * dim[2]; // total number of voxels in volume
        std::cout << "numVoxels: " << numVoxels << std::endl;
        
        int dataType; // see below
        mrc.read((char*)(&dataType), sizeof(dataType));
        std::cout << "dataType: " << dataType << std::endl;
        
        int dataSize = 0; // i.e. 8-bit, 16-bit or 32-bit
             if (dataType == 0) dataSize = 1; // signed 8-bit bytes range -128 to 127
        else if (dataType == 1) dataSize = 2; // 16-bit halfwords
        else if (dataType == 2) dataSize = 4; // 32-bit reals
        else if (dataType == 6) dataSize = 2; // unsigned 16-bit range 0 to 65535
        
        tgtAssert(dataSize, "Datasize is 0 at MRCVolumeReader::read()");
        
        int totalDataSize = dataSize * numVoxels;
        
        int start[3]; // numbers of first columns i.e. offset of the volume origin in voxel coordinates
        mrc.read((char*)(&start), sizeof(start));
        std::cout << "startX: " << start[0] << std::endl; // number of columns (fastest changing in map)
        std::cout << "startY: " << start[1] << std::endl; // number of rows
        std::cout << "startZ: " << start[2] << std::endl; // number of sections (slowest changing in map)

        int gridSize[3];
        mrc.read((char*)(&gridSize), sizeof(gridSize));
        std::cout << "gridSizeX: " << gridSize[0] << std::endl;
        std::cout << "gridSizeY: " << gridSize[1] << std::endl; 
        std::cout << "gridSizeZ: " << gridSize[2] << std::endl;
     
        float cellDimensions[3]; // cell dimensions in angstroms
        mrc.read((char*)(&cellDimensions), sizeof(cellDimensions));
        std::cout << "cellX: " << cellDimensions[0] << std::endl; 
        std::cout << "cellY: " << cellDimensions[1] << std::endl; 
        std::cout << "cellZ: " << cellDimensions[2] << std::endl; 
        
        float scale[3]; // pixelSpacing i.e. scale from voxel to real-word coordinates
        scale[0] = cellDimensions[0] / gridSize[0];
        scale[1] = cellDimensions[1] / gridSize[1];
        scale[2] = cellDimensions[2] / gridSize[2];
        std::cout << "pixelSpacingX: " << scale[0] << std::endl; 
        std::cout << "pixelSpacingY: " << scale[1] << std::endl; 
        std::cout << "pixelSpacingZ: " << scale[2] << std::endl; 
        
        float angles[3]; // cell angles in degrees
        mrc.read((char*)(&angles), sizeof(angles));
        std::cout << "cellAngleX: " << angles[0] << std::endl;
        std::cout << "cellAngleY: " << angles[1] << std::endl;
        std::cout << "cellAngleZ: " << angles[2] << std::endl;
        
        int axes[3]; // Which axis corresponds to columns, rows and sections (1,2,3 for X,Y,Z)
        mrc.read((char*)(&axes), sizeof(axes));
        std::cout << "axesX: " << axes[0] << std::endl;
        std::cout << "axesY: " << axes[1] << std::endl; 
        std::cout << "axesZ: " << axes[2] << std::endl; 
        
        float origin[3];
        mrc.seekg(4*49, std::ios::beg);
        mrc.read((char*)(&origin), sizeof(origin));
        std::cout << "originX: " << origin[0] << std::endl; 
        std::cout << "originY: " << origin[1] << std::endl; 
        std::cout << "originZ: " << origin[2] << std::endl; 
        
        void* data = malloc(totalDataSize);
        mrc.seekg(1024, std::ios::beg);
        mrc.read((char*)data, totalDataSize);
        mrc.close();
        
        VolumeRAM* targetDataset;
        
        int a = axes[0]-1;
        int b = axes[1]-1;
        int c = axes[2]-1;
        
        /**/ if (dataType == 0) {
            targetDataset = new VolumeAtomic<int8_t>(ivec3(dim[a], dim[b], dim[c]));
            fillVolume<int8_t>(targetDataset, data, dim, axes);
        }
        else if (dataType == 1) {
            targetDataset = new VolumeAtomic<int16_t>(ivec3(dim[a], dim[b], dim[c]));
            fillVolume<int16_t>(targetDataset, data, dim, axes);
        }
        else if (dataType == 2) {
            targetDataset = new VolumeAtomic<float>(ivec3(dim[a], dim[b], dim[c]));
            fillVolume<float>(targetDataset, data, dim, axes);
        }
        else if (dataType == 6) {
            targetDataset = new VolumeAtomic<uint16_t>(ivec3(dim[a], dim[b], dim[c]));
            fillVolume<uint16_t>(targetDataset, data, dim, axes);
        }
        else LERROR("Unsupported data type at MRCVolumeReader::read()");
            
        free(data);
        
        angles[0] *= (PI / 180.);
        angles[1] *= (PI / 180.);
        angles[2] *= (PI / 180.);
        
        float row[3][3];
        
        // X
        row[0][0] = 1;
        row[0][1] = 0;
        row[0][2] = 0;
        
        // Y
        row[1][0] = cos(angles[2]); // cos(gamma)
        row[1][1] = sin(angles[2]); // sin(gamma)
        row[1][2] = 0;
        
        // Z
        row[2][0] = cos(angles[1]); // cos(beta)
        row[2][1] = (cos(angles[0]) - row[2][0] * row[1][0]) / row[1][1];  // [cos(alpha) - cos(beta)*cos(gamma)] / sin(gamma)
        row[2][2] = sqrt(1 - row[2][0] * row[2][0] - row[2][1] * row[2][1]); // squared length is 1
        
        tgt::Matrix4<float> transform
        (
            row[0][0], row[1][0], row[2][0], 0,
            row[0][1], row[1][1], row[2][1], 0,
            row[0][2], row[1][2], row[2][2], 0,
            0.0f, 0.0f, 0.0f, 1.0f
        );
        
        Volume* volumeHandle = new MoleculeVolume(
            targetDataset,                                                 // data
            vec3(scale[a], scale[b], scale[c]),                            // scale
            vec3(start[a]*scale[a], start[b]*scale[b], start[c]*scale[c]), // offset
            transform                                                      // transform
        );
        
        volumeCollection->add(volumeHandle);
    }
    
    if (!volumeCollection->empty())
        volumeCollection->first()->setOrigin(VolumeURL(fileName));
        
    return volumeCollection;
}
Пример #15
0
VolumeCollection* FlowReader::read(const std::string& url)
    throw(tgt::FileException, std::bad_alloc)
{
    VolumeOrigin origin(url);
    std::string fileName = origin.getPath();

    LINFO("reading flow file '" << fileName << "'...");

    // try to open the file
    //
    std::fstream ifs(fileName.c_str(), std::ios_base::in | std::ios_base::binary);
    if (ifs.good() == false)
        throw tgt::IOException("Unable to open flow file for reading", fileName);

    // read the magic number (string "VOREENFLOW")
    //
    char magicNumber[11] = {0};
    ifs.read(magicNumber, 11);
    std::string temp(magicNumber);
    if (temp != "VOREENFLOW")
        throw tgt::IOException("Missing magic number in flow file", fileName);

    // read file version (must currently be 1 or 2)
    //
    unsigned int fileVersion = 0;
    ifs.read(reinterpret_cast<char*>(&fileVersion), sizeof(unsigned int));
    LINFO("file version: " << fileVersion);
    if ((fileVersion < 1) || (fileVersion > 2))
        throw tgt::IOException("Unsupported file version of flow file", fileName);

    // read flow dimension (usually 3 for 3D flows)
    //
    unsigned int flowDimension = 0;
    ifs.read(reinterpret_cast<char*>(&flowDimension), sizeof(unsigned int));
    LINFO("flow dimension: " << flowDimension << "D");
    if (flowDimension != 3)
        throw tgt::IOException("Unsupported flow dimension in flow file", fileName);

    unsigned char dataOrientation = 0;
    unsigned char reverseSlicesMask = 0;

    ifs.read(reinterpret_cast<char*>(&dataOrientation), sizeof(unsigned char));
    if (fileVersion > 1) {
        ifs.read(reinterpret_cast<char*>(&reverseSlicesMask), sizeof(unsigned char));
    }

    // read the dimension of the volume data containing the flow
    //
    tgt::ivec3 dimensions;
    ifs.read(reinterpret_cast<char*>(&dimensions), sizeof(tgt::ivec3));
    LINFO("volume dimensions: " << dimensions);

    unsigned int byteSize = 0;
    ifs.read(reinterpret_cast<char*>(&byteSize), sizeof(unsigned int));
    LINFO("expected size of vector field: " << byteSize << " byte");

    VolumeFlow3D* volume = readConvert(dimensions, dataOrientation, ifs);
    ifs.close();

    if (volume == 0) {
        LERROR("an error occured during reading flow data! Proceeding impossible.");
        return 0;
    }

    if (reverseSlicesMask != 0)
        reverseSlices(volume, reverseSlicesMask);

    // TODO: volume container merge
    /*VolumeSet* volumeSet = new VolumeSet(fileName);
    VolumeSeries* volumeSeries = new VolumeSeries(Modality::MODALITY_FLOW.getName(),
                                                  Modality::MODALITY_FLOW);
    volumeSet->addSeries(volumeSeries);
    VolumeHandle* volumeHandle = new VolumeHandle(volume, 0.0f);

    volumeSeries->addVolumeHandle(volumeHandle); */

    VolumeCollection* collection = new VolumeCollection();
    VolumeHandle* volumeHandle = new VolumeHandle(volume, tgt::vec3(1.0f), tgt::vec3(0.0f));//FIXME: spacing?
    oldVolumePosition(volumeHandle);
    volumeHandle->setModality(Modality::MODALITY_FLOW);
    collection->add(volumeHandle);

    // TODO: origin does not save series and timestamp anymore
    //volumeHandle->setOrigin(fileName, Modality::MODALITY_FLOW.getName(), 0.0f);
    volumeHandle->setOrigin(fileName);

    return collection;
}
Пример #16
0
void
VolumeCollectionTester::Test ( Tcl_Interp* iInterp ) {

  stringstream ssError;

  try {

    string fnMRI = "test_data/bertT1.mgz";
    VolumeCollection* vol = new VolumeCollection();
    vol->SetFileName( fnMRI );
    MRI* mri = const_cast<MRI*>(vol->GetMRI());

    Assert( (vol->GetTypeDescription() == "Volume"),
            "GetTypeDescription didn't return Volume" );

    DataManager dataMgr = DataManager::GetManager();
    MRILoader mriLoader = dataMgr.GetMRILoader();
    Assert( 1 == mriLoader.CountLoaded(),
            "CountLoaded didn't return 1" );
    Assert( 1 == mriLoader.CountReferences(mri),
            "CountReferences didn't return 1" );

    char* fnMRIC = strdup( fnMRI.c_str() );
    MRI* mriComp = MRIread( fnMRIC );

    Assert( (MRImatch( mriComp, mri )), "MRImatch failed for load" );

    MRIfree( &mriComp );


    // Save it in /tmp, load it, and match it again.
    string fnSave( "/tmp/test.mgz" );
    vol->Save( fnSave );

    VolumeCollection* testVol = new VolumeCollection();
    testVol->SetFileName( fnSave );
    MRI* testMri = const_cast<MRI*>(testVol->GetMRI());
    Assert( (MRImatch( testMri, mri )), "MRImatch failed for load after save");



    // Make an ROI and make sure it's a volume ROI.
    try {
      int roiID = vol->NewROI();
      ScubaROIVolume* roi =
        dynamic_cast<ScubaROIVolume*>(&ScubaROI::FindByID( roiID ));
      roi = NULL;
    } catch (...) {
      throw( runtime_error("typecast failed for NewROI") );
    }


    // Try our conversions.
    Point3<float> world;
    Point3<float> data;
    Point3<int> index;
    world.Set( -50, 0, -80 );
    vol->RASToMRIIndex( world.xyz(), index.xyz() );
    {
      stringstream ssError;
      ssError << "RASToMRIIndex failed. world "
      << world << " index " << index;
      Assert( (index.x() == 178 && index.y() == 208 && index.z() == 128),
              ssError.str() );
    }

    // Set a transform that scales the volume up by 2x in the world.
    ScubaTransform dataTransform;
    dataTransform.SetMainTransform( 2, 0, 0, 0,
                                    0, 2, 0, 0,
                                    0, 0, 2, 0,
                                    0, 0, 0, 1 );
    vol->SetDataToWorldTransform( dataTransform.GetID() );

    world.Set( -50, 0, -80 );
    vol->RASToDataRAS( world.xyz(), data.xyz() );
    {
      stringstream ssError;
      ssError << "RASToDataRAS failed. world "
      << world << " data " << data;
      Assert( ((FEQUAL(data.x(),-25)) &&
               (FEQUAL(data.y(),0)) &&
               (FEQUAL(data.z(),-40))),
              ssError.str() );
    }

    vol->RASToMRIIndex( world.xyz(), index.xyz() );

    if ( index.x() != 153 || index.y() != 168 || index.z() != 128 ) {
      cerr << "RASToMRIIndex with data transform failed. world "
      << world << " index " << index << endl;
      throw( runtime_error( "failed" ) );
    }


    world.Set( -50, 0, -80 );
    VolumeLocation loc( vol->MakeVolumeLocationFromRAS( world.xyz() ) );
    if ( !vol->IsInBounds( loc ) ) {
      stringstream ssError;
      ssError << "IsInBounds failed. world " << world;
      throw( runtime_error( ssError.str() ) );
    }
    world.Set( -1000, 0, 0 );
    VolumeLocation loc2( vol->MakeVolumeLocationFromRAS( world.xyz() ) );
    if ( vol->IsInBounds( loc2 ) ) {
      stringstream ssError;
      ssError << "IsInBounds failed. world " << world;
      throw( runtime_error( ssError.str() ) );
    }


    dataTransform.SetMainTransform( 2, 0, 0, 0,
                                    0, 2, 0, 0,
                                    0, 0, 2, 0,
                                    0, 0, 0, 1 );
    vol->SetDataToWorldTransform( dataTransform.GetID() );
    world.Set( 0, -1000, -254 );
    VolumeLocation loc3( vol->MakeVolumeLocationFromRAS( world.xyz() ) );
    if ( vol->IsInBounds( loc3 ) ) {
      stringstream ssError;
      vol->RASToMRIIndex( world.xyz(), index.xyz() );
      ssError << "IsRASInMRIBounds failed. world " << world
      << " index " << index;
      throw( runtime_error( ssError.str() ) );
    }


    {
      // Create a new one from template.
      VolumeCollection* vol2 = new VolumeCollection();
      vol2->MakeUsingTemplate( vol->GetID(), -1 );
      Assert( (vol->mVoxelSize[0] == vol2->mVoxelSize[0] &&
	       vol->mVoxelSize[1] == vol2->mVoxelSize[1] &&
	       vol->mVoxelSize[2] == vol2->mVoxelSize[2]),
	      "NewUsingTemplate failed, vol2 didn't match vol's voxelsize" );
      Assert( (vol->GetDataType() == vol2->GetDataType()),
	    "NewUsingTemplate(-1) failed, vol2 didn't match vol's data type" );
      delete vol2;
    }
    
    {
      VolumeCollection* vol2 = new VolumeCollection();
      vol2->MakeUsingTemplate( vol->GetID(), MRI_FLOAT );
      Assert( (vol->mVoxelSize[0] == vol2->mVoxelSize[0] &&
	       vol->mVoxelSize[1] == vol2->mVoxelSize[1] &&
	       vol->mVoxelSize[2] == vol2->mVoxelSize[2]),
	      "NewUsingTemplate failed, vol2 didn't match vol's voxelsize" );
      Assert( (MRI_FLOAT == vol2->GetDataType()),
	      "NewUsingTemplate(float) failed, vol2 wasn't a float" );
      
      int idx[3] = { 0, 0, 0 };
      VolumeLocation loc( vol2->MakeVolumeLocationFromIndex( idx ) );
      vol2->SetMRIValue( loc, 0.6789 );
      float value = vol2->GetMRINearestValue(loc);

      stringstream ssError;
      ssError << "NewUsingTemplate(float) failed value comparison, "
	      << "was expecting 0.6789 but got " << value;
      Assert( (fabs(0.6789 - value) < 0.00001), ssError.str() );
      delete vol2;
    }

    {
      VolumeCollection* vol2 = NULL;
      try {
	vol2 = new VolumeCollection();
	vol2->MakeUsingTemplate( vol->GetID(), 10000 );
	throw runtime_error( "MakeUsingTemplate(10000) didn't throw an error");
      }
      catch(...) {}
      delete vol2;
    }

    dataTransform.SetMainTransform( 1, 0, 0, 0,
                                    0, 1, 0, 0,
                                    0, 0, 1, 0,
                                    0, 0, 0, 1 );
    vol->SetDataToWorldTransform( dataTransform.GetID() );

    // FindRASPointsInSquare
    {
      Point3<float> sqRAS[4], cRAS;
      sqRAS[0].Set( 0, -3, 71 );
      sqRAS[1].Set( 0, 1, 71 );
      sqRAS[2].Set( 0, 1, 67 );
      sqRAS[3].Set( 0, -3, 67 );
      cRAS.Set( 0, -1, 69 );
      list<Point3<float> > points;
      vol->FindRASPointsInSquare( cRAS.xyz(),
                                  sqRAS[0].xyz(), sqRAS[1].xyz(),
                                  sqRAS[2].xyz(), sqRAS[3].xyz(),
                                  0, points );
      list<Point3<float> >::iterator tPoint;
      for ( tPoint = points.begin(); tPoint != points.end(); ++tPoint ) {
        Point3<float> pRAS = *tPoint;

        stringstream ssMsg;
        ssMsg << "Failed: " << pRAS << " outside of square";

        Assert( ( pRAS[0] == 0 &&
                  (pRAS[1] >= -3 && pRAS[1] <= 1) &&
                  (pRAS[2] >= 67 && pRAS[2] <= 71) ),
                ssMsg.str() );
      }
    }


    // VoxelIntersectsSegment
    {
      Point3<int> idx;
      Point3<float> segIdxA, segIdxB;
      Point3<float> intIdx;

      idx.Set( 5, 5, 5 );

      float aSegments[6][3] = { {3, 5.5, 5.5}, {6, 5.5, 5.5},
                                {5.5, 3, 5.5}, {5.5, 6, 5.5},
                                {5.5, 5.5, 3}, {5.5, 5.5, 6} };
      for ( int nSegment = 0; nSegment < 6; nSegment += 2 ) {

        segIdxA.Set( aSegments[nSegment] );
        segIdxB.Set( aSegments[nSegment+1] );

        VectorOps::IntersectionResult rInt =
          vol->VoxelIntersectsSegment( idx, segIdxA, segIdxB, intIdx );

        if ( VectorOps::intersect != rInt ) {
          cerr << "Failed VoxelIntersectsSegment test: idx " << idx
          << ", seg " << segIdxA << ", " << segIdxB << endl
          << "\tDidn't intersect" << endl;
          throw runtime_error("failed");
        }
      }

      segIdxA.Set( 0, 5.5, 5.5 );
      segIdxB.Set( 4, 5.5, 5.5 );
      VectorOps::IntersectionResult rInt =
        vol->VoxelIntersectsSegment( idx, segIdxA, segIdxB, intIdx );

      if ( VectorOps::dontIntersect != rInt ) {
        cerr << "Failed VoxelIntersectsSegment test: idx " << idx
        << ", seg " << segIdxA << ", " << segIdxB << endl
        << "\tIntersected" << endl;
        throw runtime_error("failed");
      }
    }

    // FindRASPointsOnSegment
    {

    }


    // GetVoxelsWithValue
    {
      // This is a 5cubed volume whose values are set to the x
      // coordinate. So for x=3,y=0..4,z=0..4, value = 3.
      string fnVol = "test_data/testVolumeCollection-GetVoxelsWithValue.mgh";
      ifstream fVol( fnMRI.c_str(), ios::in );
      if ( !fVol ) {
        throw runtime_error("Couldn't find necessary test data.");
      }
      fVol.close();

      VolumeCollection* vol = new VolumeCollection();
      vol->SetFileName( fnVol );
      vol->LoadVolume();

      // Get the values 0-4 and make sure we got the right voxels.
      for ( int nStructure = 0; nStructure < 5; nStructure++ ) {

        list<VolumeLocation> lLocations;
        vol->GetVoxelsWithValue( nStructure, lLocations );

        Volume3<bool> bGot( 5, 5, 5, false );
        list<VolumeLocation>::iterator tLocation;
        for ( tLocation = lLocations.begin(); tLocation != lLocations.end();
              ++tLocation ) {

          VolumeLocation loc = *(tLocation);
          bGot.Set( loc.Index()[0], loc.Index()[1], loc.Index()[2], true );
        }

        for ( int nZ = 0; nZ < 5; nZ++ ) {
          for ( int nY = 0; nY < 5; nY++ ) {
            for ( int nX = 0; nX < 5; nX++ ) {
              if ( nX == nStructure && !bGot.Get( nX, nY, nZ ) ) {
                stringstream ssErr;
                ssErr << "Failed GetVoxelsWithValue test: "
                << " nStructure = " << nStructure
                << " index " << Point3<int>(nX,nY,nZ)
                << " - was supposed to get voxel but didn't";
                throw runtime_error(ssErr.str());
              }
              if ( nX != nStructure && bGot.Get( nX, nY, nZ ) ) {
                stringstream ssErr;
                ssErr << "Failed GetVoxelsWithValue test: "
                << " nStructure = " << nStructure
                << " index " << Point3<int>(nX,nY,nZ)
                << " - wasn't supposed to get voxel but did";
                throw runtime_error(ssErr.str());
              }
            }
          }
        }
      }

      delete vol;
    }

    // GetAverageValue
    {
      // We'll use the same volume as with GetVoxelsWithValue.
      string fnVol = "test_data/testVolumeCollection-GetVoxelsWithValue.mgh";
      ifstream fVol( fnMRI.c_str(), ios::in );
      if ( !fVol ) {
        throw runtime_error("Couldn't find necessary test data.");
      }
      fVol.close();

      VolumeCollection* vol = new VolumeCollection();
      vol->SetFileName( fnVol );
      vol->LoadVolume();

      // Get values of all voxels in plane x=3 and make sure it's 3.
      list<VolumeLocation> lVoxels;
      for ( int nZ = 0; nZ < 5; nZ++ ) {
        for ( int nY = 0; nY < 5; nY++ ) {
          int index[3] = { 3, nY, nZ };
          VolumeLocation loc( vol->MakeVolumeLocationFromIndex( index ) );
          lVoxels.push_back( loc );
        }
      }
      float average = vol->GetAverageValue( lVoxels );
      if ( average != 3.0 ) {
        stringstream ssErr;
        ssErr << "Failed GetAverageValue: Getting all voxels in x=3, "
        << "average should have been 3, but was " << average;
        throw runtime_error( ssErr.str() );
      }

      // Get values of 5 voxels, one from each x plane
      // (val=0,1,2,3,4), and make sure it's 2.
      lVoxels.clear();
      for ( int nX = 0; nX < 5; nX++ ) {
        int index[3] = { nX, 3, 3 };
        VolumeLocation loc( vol->MakeVolumeLocationFromIndex( index ) );
        lVoxels.push_back( loc );
      }
      average = vol->GetAverageValue( lVoxels );
      if ( average != 2.0 ) {
        stringstream ssErr;
        ssErr << "Failed GetAverageValue: Getting voxels in different planes, "
        << "average should have been 2, but was " << average;
        throw runtime_error( ssErr.str() );
      }

      // Make sure we get an error for no voxels.
      lVoxels.clear();
      bool bDidntThrow = false;
      try {
        average = vol->GetAverageValue( lVoxels );
        bDidntThrow = true;
      } catch ( exception& e ) {}
      if ( bDidntThrow ) {
        stringstream ssErr;
        ssErr << "Failed GetAverageValue: Didn't throw with empty list";
        throw runtime_error( ssErr.str() );
      }

      delete vol;
    }


    // Check the tcl commands.
    char sCommand[1024];
    int rTcl;

    int id = vol->GetID();
    string fnTest = "test-name";
    sprintf( sCommand, "SetVolumeCollectionFileName %d test-name", id );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    Assert( (vol->mfnMRI == fnTest),
            "Setting file name via tcl didn't work" );

    vol->SetDataToWorldTransform( 0 );

    delete vol;
    delete testVol;
  } catch ( exception& e ) {
    cerr << "failed with exception: " << e.what() << endl;
    exit( 1 );
  } catch (...) {
    cerr << "failed." << endl;
    exit( 1 );
  }
}
void
SegmentationVolumeReportTester::Test ( Tcl_Interp* iInterp ) {

  try {


    // Load our seg volume.
    string fnSegVolume = "test_data/testSegmentationVolumeReportData-Seg.mgz";
    VolumeCollection seg;
    seg.SetFileName( fnSegVolume );
    seg.LoadVolume();
    seg.SetLabel( "Seg" );

    // Load our intensity volume.
    string fnIntVolume = "test_data/testSegmentationVolumeReportData-Int.mgz";
    VolumeCollection vol;
    vol.SetFileName( fnIntVolume );
    vol.LoadVolume();
    vol.SetLabel( "Int" );


    // Load our LUT.
    string fnLUT = "test_data/TestLUT.txt";
    ScubaColorLUT lut;
    lut.UseFile( fnLUT );

    // Set up the report.
    SegmentationVolumeReport& report =
      SegmentationVolumeReport::GetReport();

    report.SetSegmentation( seg );
    if ( NULL == report.mSegVol ) {
      stringstream ssError;
      ssError << "Error on SetSegmentation, mSegVol was NULL";
      throw runtime_error( ssError.str() );
    }
    if ( report.mSegVol->GetID() != seg.GetID() ) {
      stringstream ssError;
      ssError << "Error on SetSegmentation, mSegVol was the wrong volume (should be ID " << seg.GetID() << " but was " << report.mSegVol->GetID();
      throw runtime_error( ssError.str() );
    }

    report.DontUseROI();
    if ( report.mbUseROI ) {
      stringstream ssError;
      ssError << "Error on DontUseROI, mbUseROI was true";
      throw runtime_error( ssError.str() );
    }


    report.SetColorLUT( lut );
    if ( NULL == report.mLUT ) {
      stringstream ssError;
      ssError << "Error on SetColorLUT, mROI was NULL";
      throw runtime_error( ssError.str() );
    }
    if ( report.mLUT->GetID() != lut.GetID() ) {
      stringstream ssError;
      ssError << "Error on SetColorLUT, id didn't match";
      throw runtime_error( ssError.str() );
    }

    // Add 1-5 but not 3.
    report.AddSegmentationStructure( 1 );
    report.AddSegmentationStructure( 2 );
    report.AddSegmentationStructure( 4 );
    report.AddSegmentationStructure( 5 );
    map<int,bool> structureMap;
    list<int>::iterator tStructure;
    for ( tStructure = report.mlStructures.begin();
          tStructure != report.mlStructures.end(); ++tStructure ) {
      int nStructure = *tStructure;
      if ( nStructure != 1 && nStructure != 2 &&
           nStructure != 4 && nStructure != 5 ) {
        stringstream ssError;
        ssError << "Error on AddSegmentationStructure, added an unknown structure " << nStructure;
        throw runtime_error( ssError.str() );
      }
      structureMap[nStructure] = true;
    }
    if ( !(structureMap[1] && structureMap[2] &&
           structureMap[4] && structureMap[5]) ) {
      stringstream ssError;
      ssError << "Error in AddSegmentationStructure, didn't add all structures";
      throw runtime_error( ssError.str() );
    }

    // Test handling of undefined structures.
    report.AddSegmentationStructure( 200 );

    // Add the intensity volume. Also add the seg vol as an additional
    // intensity volume.
    report.AddIntensityVolume( vol );
    report.AddIntensityVolume( seg );
    map<int,bool> volsLoadedMap;
    list<VolumeCollection*>::iterator tVolume;
    for ( tVolume = report.mlIntVols.begin();
          tVolume != report.mlIntVols.end(); ++tVolume ) {
      VolumeCollection* testVol = *tVolume;
      int volID = testVol->GetID();
      if ( volID != vol.GetID() && volID != seg.GetID() ) {
        stringstream ssError;
        ssError << "Error in AddIntensityVolume, added a volume with an unknown id " << volID;
        throw runtime_error( ssError.str() );
      }
      volsLoadedMap[volID] = true;
    }
    if ( !(volsLoadedMap[vol.GetID()] && volsLoadedMap[seg.GetID()]) ) {
      stringstream ssError;
      ssError << "Error in AddIntensityVolume, didn't add both volumes";
      throw runtime_error( ssError.str() );
    }

    report.MakeVolumeReport();


    for ( int nStructure = 1; nStructure <= 5; nStructure++ ) {

      // Check the number of voxels we got.
      float expectedSize;
      if ( nStructure == 3 ) {
        expectedSize = 0;
      } else {
        expectedSize = 25 * 25;
      }
      if ( report.mStructureToVolumeMap[nStructure] != expectedSize ) {
        stringstream ssError;
        ssError << "Error on report for seg " << nStructure
        << ": expectedSize was " << expectedSize << ", but got "
        << report.mStructureToVolumeMap[nStructure];
        throw runtime_error( ssError.str() );
      }

      // Check the intensity values (for the vol, should be 2x the
      // segmentation index, and for the seg, should be ==).
      float expectedIntensityAverage;
      if ( nStructure == 3 ) {
        expectedIntensityAverage = 0;
      } else {
        expectedIntensityAverage = nStructure * 2.0;
      }
      if ( report.mVolumeToIntensityAverageMap[&vol][nStructure] !=
           expectedIntensityAverage ) {
        stringstream ssError;
        ssError << "Error on report for seg " << nStructure
        << ": expectedIntensityAverage for intensity vol " << &vol
        << " was " << expectedIntensityAverage << ", but got "
        << report.mVolumeToIntensityAverageMap[&vol][nStructure];
        throw runtime_error( ssError.str() );
      }

      if ( nStructure == 3 ) {
        expectedIntensityAverage = 0;
      } else {
        expectedIntensityAverage = nStructure;
      }
      if ( report.mVolumeToIntensityAverageMap[&seg][nStructure] !=
           expectedIntensityAverage ) {
        stringstream ssError;
        ssError << "Error on report for seg " << nStructure
        << ": expectedIntensityAverage for seg vol " << &seg
        << " was " << expectedIntensityAverage << ", but got "
        << report.mVolumeToIntensityAverageMap[&seg][nStructure];
        throw runtime_error( ssError.str() );
      }
    }

    // Make the report.
    report.MakeVolumeReport( "/tmp/testReport.txt" );

    // Compare it with the correct one.
    int rDiff =
      system( "diff /tmp/testReport.txt testSegmentationVolumeReport-correct.txt" );
    if ( rDiff != 0 ) {
      throw runtime_error( "diff failed on testReport" );
    }

    // Make the report.
    report.MakeIntensityReport( "/tmp/testIntReport.txt" );

    // Compare it with the correct one.
    rDiff =
      system( "diff /tmp/testIntReport.txt testSegmentationVolumeReportIntReport-correct.txt" );
    if ( rDiff != 0 ) {
      throw runtime_error( "diff failed on testIntReport" );
    }

    // Test the tcl functions now. Just call them all and check the
    // results. Need to clear the report first.
    report.Clear();
    if ( NULL != report.mSegVol ||
         report.mlIntVols.size() != 0 ||
         report.mbUseROI ||
         NULL != report.mROIVol ||
         NULL != report.mROI ||
         NULL != report.mLUT ||
         report.mlStructures.size() != 0 ||
         !report.mbReportDirty ||
         report.mVolumeToIntensityAverageMap.size() != 0 ||
         report.mStructureToVolumeVoxelListMap.size() != 0 ) {
      stringstream ssError;
      ssError << "Error on Clear: not cleared";
      throw runtime_error( ssError.str() );
    }

    char sCommand[1024];
    int rTcl;

    sprintf( sCommand, "SetSegVolReportSegmentation %d", seg.GetID() );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );

    if ( NULL == report.mSegVol ) {
      stringstream ssError;
      ssError << "Error on Tcl SetSegVolReportSegmentation, mSegVol was NULL";
      throw runtime_error( ssError.str() );
    }
    if ( report.mSegVol->GetID() != seg.GetID() ) {
      stringstream ssError;
      ssError << "Error on Tcl SetSegVolReportSegmentation, mSegVol was the wrong volume (should be ID " << seg.GetID() << " but was " << report.mSegVol->GetID();
      throw runtime_error( ssError.str() );
    }

    sprintf( sCommand, "AddSegVolReportIntensityVolume %d", vol.GetID() );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );

    sprintf( sCommand, "AddSegVolReportIntensityVolume %d", seg.GetID() );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );

    volsLoadedMap.clear();
    for ( tVolume = report.mlIntVols.begin();
          tVolume != report.mlIntVols.end(); ++tVolume ) {
      VolumeCollection* testVol = *tVolume;
      int volID = testVol->GetID();
      if ( volID != vol.GetID() && volID != seg.GetID() ) {
        stringstream ssError;
        ssError << "Error in Tcl AddSegVolReportIntensityVolume, added a volume with an unknown id " << volID;
        throw runtime_error( ssError.str() );
      }
      volsLoadedMap[volID] = true;
    }
    if ( !(volsLoadedMap[vol.GetID()] && volsLoadedMap[seg.GetID()]) ) {
      stringstream ssError;
      ssError << "Error in Tcl AddSegVolReportIntensityVolume, didn't add both volumes";
      throw runtime_error( ssError.str() );
    }

    sprintf( sCommand, "AddSegmentationToSegVolReport 1" );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    sprintf( sCommand, "AddSegmentationToSegVolReport 2" );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    sprintf( sCommand, "AddSegmentationToSegVolReport 4" );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    sprintf( sCommand, "AddSegmentationToSegVolReport 5" );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    structureMap.clear();
    for ( tStructure = report.mlStructures.begin();
          tStructure != report.mlStructures.end(); ++tStructure ) {
      int nStructure = *tStructure;
      if ( nStructure != 1 && nStructure != 2 &&
           nStructure != 4 && nStructure != 5 ) {
        stringstream ssError;
        ssError << "Error on Tcl AddSegmentationToSegVolReport, added an unknown structure " << nStructure;
        throw runtime_error( ssError.str() );
      }
      structureMap[nStructure] = true;
    }
    if ( !(structureMap[1] && structureMap[2] &&
           structureMap[4] && structureMap[5]) ) {
      stringstream ssError;
      ssError << "Error in Tcl AddSegmentationToSegVolReport, didn't add all structures";
      throw runtime_error( ssError.str() );
    }

    report.AddSegmentationStructure( 200 );

    sprintf( sCommand, "SetSegVolReportLUT %d", lut.GetID() );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    if ( NULL == report.mLUT ) {
      stringstream ssError;
      ssError << "Error on Tcl SetSegVolReportLUT, mLUT was NULL";
      throw runtime_error( ssError.str() );
    }
    if ( report.mLUT->GetID() != lut.GetID() ) {
      stringstream ssError;
      ssError << "Error on Tcl SetSegVolReportLUT, id didn't match";
      throw runtime_error( ssError.str() );
    }

    sprintf( sCommand, "MakeSegVolReport /tmp/testReport2.txt" );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    rDiff =
      system( "diff /tmp/testReport2.txt testSegmentationVolumeReport-correct.txt" );
    if ( rDiff != 0 ) {
      throw runtime_error( "diff failed on testReport in Tcl MakeSegVolReport" );
    }

    sprintf( sCommand, "MakeSegVolIntensityReport /tmp/testIntReport2.txt" );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    rDiff =
      system( "diff /tmp/testIntReport2.txt testSegmentationVolumeReportIntReport-correct.txt" );
    if ( rDiff != 0 ) {
      throw runtime_error( "diff failed on testIntReport in Tcl MakeSegVolIntensityReport" );
    }

    sprintf( sCommand, "ClearSegVolReport" );
    rTcl = Tcl_Eval( iInterp, sCommand );
    AssertTclOK( rTcl );
    if ( NULL != report.mSegVol ||
         report.mlIntVols.size() != 0 ||
         report.mbUseROI ||
         NULL != report.mROIVol ||
         NULL != report.mROI ||
         NULL != report.mLUT ||
         report.mlStructures.size() != 0 ||
         !report.mbReportDirty ||
         report.mVolumeToIntensityAverageMap.size() != 0 ||
         report.mStructureToVolumeVoxelListMap.size() != 0 ) {
      stringstream ssError;
      ssError << "Error on Tcl ClearSegVolReport: not cleared";
      throw runtime_error( ssError.str() );
    }

  } catch ( exception& e ) {
    cerr << "failed with exception: " << e.what() << endl;
    exit( 1 );
  } catch (...) {
    cerr << "failed." << endl;
    exit( 1 );
  }
}
Пример #18
0
VolumeCollection* AnalyzeVolumeReader::readAnalyze(const std::string &fileName, int volId)
    throw (tgt::FileException, std::bad_alloc)
{
    LINFO("Loading analyze file " << fileName);
    LINFO("Related img file: " << getRelatedImgFileName(fileName));

    std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary);
    if(!file) {
        throw tgt::FileNotFoundException("Failed to open file: ", fileName);
    }

    file.seekg(0, std::ios::end);
    std::streamoff fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

    if(fileSize != 348)
        LWARNING("Filesize != 348");

    header_key header;
    if (!file.read((char*)&header, sizeof(header))) {
        throw tgt::CorruptedFileException("Failed to read header!", fileName);
    }

    image_dimension dimension;
    if (!file.read((char*)&dimension, sizeof(dimension))) {
        throw tgt::CorruptedFileException("Failed to read dimensions!", fileName);
    }

    data_history history;
    if (!file.read((char*)&history, sizeof(history))) {
        throw tgt::CorruptedFileException("Failed to read history!", fileName);
    }

    bool bigEndian = false;
    //check if swap is necessary:
    if((dimension.dim[0] < 0) || (dimension.dim[0] > 15)) {
        bigEndian = true;
        header.swapEndianess();
        dimension.swapEndianess();
        history.swapEndianess();
    }

    ivec3 dimensions;
    dimensions.x = dimension.dim[1];
    dimensions.y = dimension.dim[2];
    dimensions.z = dimension.dim[3];
    LINFO("Resolution: " << dimensions);

    int numVolumes = dimension.dim[4];
    LINFO("Number of volumes: " << numVolumes);

    if (hor(lessThanEqual(dimensions, ivec3(0)))) {
        LERROR("Invalid resolution or resolution not specified: " << dimensions);
        throw tgt::CorruptedFileException("error while reading data", fileName);
    }

    vec3 spacing;
    spacing.x = dimension.pixdim[1];
    spacing.y = dimension.pixdim[2];
    spacing.z = dimension.pixdim[3];
    LINFO("Spacing: " << spacing);

    LINFO("Datatype: " << dimension.datatype);

    std::string voreenVoxelType;
    switch(dimension.datatype) {
        case DT_UNSIGNED_CHAR:
            voreenVoxelType = "uint8";
            break;
        case DT_SIGNED_SHORT:
            voreenVoxelType = "int16";
            break;
        case DT_SIGNED_INT:
            voreenVoxelType = "int32";
            break;
        case DT_FLOAT:
            voreenVoxelType = "float";
            break;
        case DT_DOUBLE:
            voreenVoxelType = "double";
            break;
        case DT_RGB:
            voreenVoxelType = "Vector3(uint8)";
            break;
        case DT_ALL:
        case DT_COMPLEX:
        case 0: //DT_NONE/DT_UNKNOWN
        case DT_BINARY:
        default:
            throw tgt::UnsupportedFormatException("Unsupported datatype!");
    }

    std::string objectType;
    std::string gridType;

    int start = 0;
    int stop = numVolumes;
    if(volId != -1) {
        //we want to load a single volume:
        start = volId;
        stop = start + 1;
    }

    // Nifti transformations give us the center of the first voxel, we translate to correct:
    mat4 pToW = mat4::createTranslation(-spacing * 0.5f);

    VolumeCollection* vc = new VolumeCollection();
    size_t volSize = hmul(tgt::svec3(dimensions)) * (dimension.bitpix / 8);
    for(int i=start; i<stop; i++) {
        VolumeRepresentation* volume = new VolumeDisk(getRelatedImgFileName(fileName), voreenVoxelType, dimensions, i * volSize, bigEndian);
        Volume* vh = new Volume(volume, spacing, vec3(0.0f));
        vh->setOrigin(VolumeURL(fileName));
        vh->setPhysicalToWorldMatrix(pToW);

        VolumeURL origin(fileName);
        origin.addSearchParameter("volumeId", itos(i));
        vh->setOrigin(origin);

        vc->add(vh);
    }

    return vc;
}
Пример #19
0
VolumeCollection* AnalyzeVolumeReader::readNifti(const std::string &fileName, bool standalone, int volId)
    throw (tgt::FileException, std::bad_alloc)
{
    LINFO("Loading nifti file " << fileName);

    std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary);
    if(!file) {
        throw tgt::FileNotFoundException("Failed to open file: ", fileName);
    }

    nifti_1_header header;
    if (!file.read((char*)&header, sizeof(header))) {
        throw tgt::CorruptedFileException("Failed to read header!", fileName);
    }

    file.close();

    bool bigEndian = false;
    //check if swap is necessary:
    if((header.dim[0] < 0) || (header.dim[0] > 15)) {
        bigEndian = true;
        header.swapEndianess();
    }

    if(header.sizeof_hdr != 348) {
        throw tgt::CorruptedFileException("Invalid header.sizeof_hdr", fileName);
    }

    if(!( (header.magic[0] == 'n') && (header.magic[2] == '1') && (header.magic[3] == 0) ))
        throw tgt::CorruptedFileException("Not a Nifti header!", fileName);

    if(header.magic[1] == '+') {
        if(!standalone)
            LWARNING("Tried to read standalone Nifti as hdr+img!");
        standalone = true;
    }
    else if(header.magic[1] == 'i') {
        if(!standalone)
            LWARNING("Tried to read hdr+img Nifti as standalone!");
        standalone = false;
    }
    else
        throw tgt::CorruptedFileException("Not a Nifti header!", fileName);

    ivec3 dimensions;
    dimensions.x = header.dim[1];
    dimensions.y = header.dim[2];
    dimensions.z = header.dim[3];
    LINFO("Resolution: " << dimensions);

    int numVolumes = header.dim[4];
    LINFO("Number of volumes: " << numVolumes);

    if (hor(lessThanEqual(dimensions, ivec3(0)))) {
        LERROR("Invalid resolution or resolution not specified: " << dimensions);
        throw tgt::CorruptedFileException("error while reading data", fileName);
    }

    vec3 spacing;
    spacing.x = header.pixdim[1];
    spacing.y = header.pixdim[2];
    spacing.z = header.pixdim[3];
    LINFO("Spacing: " << spacing);

    int timeunit = XYZT_TO_TIME(header.xyzt_units);
    int spaceunit = XYZT_TO_SPACE(header.xyzt_units);
    LINFO("timeunit: " << timeunit << " spaceunit: " << spaceunit);

    float dt = header.pixdim[4];
    float toffset = header.toffset;
    switch(timeunit) {
        case NIFTI_UNITS_SEC:
            dt *= 1000.0f;
            toffset *= 1000.0f;
            break;
        case NIFTI_UNITS_MSEC:
            //nothing to do
            break;
        case NIFTI_UNITS_USEC:
            dt /= 1000.0f;
            toffset /= 1000.0f;
            break;
    }

    switch(spaceunit) {
        case NIFTI_UNITS_MM:
            //nothing to do
            break;
        case NIFTI_UNITS_METER:
            spacing *= 1000.0f;
            LWARNING("Units: meter");
            break;
        case NIFTI_UNITS_MICRON:
            spacing /= 1000.0f;
            LWARNING("Units: micron");
            break;
        case NIFTI_UNITS_UNKNOWN:
        default:
            LWARNING("Unknown space unit!");
            break;
    }

    LINFO("Datatype: " << header.datatype);
    std::string voreenVoxelType = "";
    RealWorldMapping denormalize;
    bool applyRWM = header.scl_slope != 0.0f;

    switch(header.intent_code) {
        case IC_INTENT_SYMMATRIX:  /* parameter at each voxel is symmetrical matrix */
            //TODO: should be relatively easy (=> tensors)
        case IC_INTENT_DISPVECT:   /* parameter at each voxel is displacement vector */
        case IC_INTENT_VECTOR:     /* parameter at each voxel is vector */
            //TODO: should be relatively easy
        case IC_INTENT_GENMATRIX:  /* parameter at each voxel is matrix */
            //TODO: should be relatively easy
        case IC_INTENT_POINTSET:   /* value at each voxel is spatial coordinate (vertices/nodes of surface mesh) */
        case IC_INTENT_TRIANGLE:   /* value at each voxel is spatial coordinate (vertices/nodes of surface mesh) */
        case IC_INTENT_QUATERNION:
            throw tgt::UnsupportedFormatException("Unsupported intent code!");
            break;
        case IC_INTENT_ESTIMATE:   /* parameter for estimate in intent_name */
        case IC_INTENT_LABEL:      /* parameter at each voxel is index to label defined in aux_file */
        case IC_INTENT_NEURONAME:  /* parameter at each voxel is index to label in NeuroNames label set */
        case IC_INTENT_DIMLESS:    /* dimensionless value */
        case IC_INTENT_NONE:
            break;
        default:
            LWARNING("Unhandled intent code");
            break;
    }
    //if (header.intent_code == IC_INTENT_SYMMATRIX) {
        //h.objectModel_ = "TENSOR_FUSION_LOW";
    //}
    if(voreenVoxelType == "") {
        switch(header.datatype) {
            case DT_UNSIGNED_CHAR:
                voreenVoxelType = "uint8";
                denormalize = RealWorldMapping::createDenormalizingMapping<uint8_t>();
                break;
            case DT_SIGNED_SHORT:
                voreenVoxelType = "int16";
                denormalize = RealWorldMapping::createDenormalizingMapping<int16_t>();
                break;
            case DT_SIGNED_INT:
                voreenVoxelType = "int32";
                denormalize = RealWorldMapping::createDenormalizingMapping<int32_t>();
                break;
            case DT_FLOAT:
                voreenVoxelType = "float";
                break;
            case DT_DOUBLE:
                voreenVoxelType = "double";
                break;
            case DT_RGB:
                voreenVoxelType = "Vector3(uint8)";
                applyRWM = false;
                break;
            case DT_RGBA32:         /* 4 byte RGBA (32 bits/voxel)  */
                voreenVoxelType = "Vector4(uint8)";
                applyRWM = false;
                break;
            case DT_INT8:           /* signed char (8 bits)         */
                voreenVoxelType = "int8";
                break;
            case DT_UINT16:         /* unsigned short (16 bits)     */
                voreenVoxelType = "uint16";
                denormalize = RealWorldMapping::createDenormalizingMapping<uint16_t>();
                break;
            case DT_UINT32:         /* unsigned int (32 bits)       */
                voreenVoxelType = "uint32";
                denormalize = RealWorldMapping::createDenormalizingMapping<uint32_t>();
                break;
            case DT_INT64:          /* long long (64 bits)          */
            case DT_UINT64:         /* unsigned long long (64 bits) */
            case DT_FLOAT128:       /* long double (128 bits)       */
            case DT_COMPLEX128:     /* double pair (128 bits)       */
            case DT_COMPLEX256:     /* long double pair (256 bits)  */
            case DT_ALL:
            case DT_COMPLEX:
            case 0: //DT_NONE/DT_UNKNOWN
            case DT_BINARY:
            default:
                throw tgt::UnsupportedFormatException("Unsupported datatype!");
        }
    }

    RealWorldMapping rwm(header.scl_slope, header.scl_inter, "");

    int headerskip = static_cast<uint16_t>(header.vox_offset);

    std::string rawFilename = fileName;
    if(!standalone)
        rawFilename = getRelatedImgFileName(fileName);

    mat4 pToW = mat4::identity;

    //Calculate transformation:
    if(header.sform_code > 0) {
        mat4 vToW(header.srow_x[0], header.srow_x[1], header.srow_x[2], header.srow_x[3],
                  header.srow_y[0], header.srow_y[1], header.srow_y[2], header.srow_y[3],
                  header.srow_z[0], header.srow_z[1], header.srow_z[2], header.srow_z[3],
                  0.0f, 0.0f, 0.0f, 1.0f);

        mat4 wToV = mat4::identity;
        if(!vToW.invert(wToV)) {
            LERROR("Failed to invert voxel to world matrix!");
        }

        mat4 vToP = mat4::createScale(spacing); //no offset
        pToW = vToP * wToV;
    }
    else if(header.qform_code > 0) {
        float b = header.quatern_b;
        float c = header.quatern_c;
        float d = header.quatern_d;
        float a = static_cast<float>(sqrt(1.0-(b*b+c*c+d*d)));

        mat4 rot2(a*a+b*b-c*c-d*d,   2*b*c-2*a*d,       2*b*d+2*a*c,     0.0f,
                  2*b*c+2*a*d,       a*a+c*c-b*b-d*d,   2*c*d-2*a*b,     0.0f,
                  2*b*d-2*a*c,       2*c*d+2*a*b,       a*a+d*d-c*c-b*b, 0.0f,
                  0.0f,              0.0f,              0.0f,            1.0f);

        float qfac = header.pixdim[0];
        if(fabs(qfac) < 0.1f)
            qfac = 1.0f;
        mat4 sc = mat4::createScale(vec3(1.0f, 1.0f, qfac));

        mat4 os = mat4::createTranslation(vec3(header.qoffset_x, header.qoffset_y, header.qoffset_z));
        pToW = os * rot2 * sc;
    }

    // Nifti transformations give us the center of the first voxel, we translate to correct:
    pToW = pToW * mat4::createTranslation(-spacing * 0.5f);

    VolumeCollection* vc = new VolumeCollection();
    size_t volSize = hmul(tgt::svec3(dimensions)) * (header.bitpix / 8);

    int start = 0;
    int stop = numVolumes;
    if(volId != -1) {
        //we want to load a single volume:
        start = volId;
        stop = start + 1;
    }

    for(int i=start; i<stop; i++) {
        VolumeRepresentation* volume = new VolumeDisk(rawFilename, voreenVoxelType, dimensions, headerskip + (i * volSize), bigEndian);
        Volume* vh = new Volume(volume, spacing, vec3(0.0f));

        VolumeURL origin(fileName);
        origin.addSearchParameter("volumeId", itos(i));
        vh->setOrigin(origin);

        vh->setPhysicalToWorldMatrix(pToW);
        vh->setMetaDataValue<StringMetaData>("Description", std::string(header.descrip));
        //vh->addMetaData("ActualFrameDuration", new IntMetaData(ih_.frame_duration));
        //vh->addMetaData("FrameTime", new IntMetaData(ih_.frame_start_time));
        vh->setMetaDataValue<IntMetaData>("FrameTime", static_cast<int>(toffset + (i * dt)));
        if(applyRWM)
            vh->setRealWorldMapping(RealWorldMapping::combine(denormalize, rwm));

        vc->add(vh);
    }

    return vc;
}
Пример #20
0
int main( int argc, char **argv ) {
    try {

        QApplication a( argc, argv );


        string fnMRI = "/Users/kteich/work/subjects/bert/mri/orig";

        char* sSubjectsDir = getenv("SUBJECTS_DIR");

        if ( NULL != sSubjectsDir ) {
            fnMRI = string(sSubjectsDir) + "/bert/mri/orig";
        }

        if ( argc == 2 ) {
            fnMRI = argv[1];
        }

        VolumeCollection vol;
        vol.SetFileName( fnMRI );
        MRI* mri = vol.GetMRI();
        if ( NULL == mri )
            exit( 1 );

        QtVolumeHistogram* histogram;
        histogram = new QtVolumeHistogram( 0, (const char*) "QtVolumeHistogram" );
        histogram->SetVolumeSource( &vol );
        histogram->SetNumberOfBins( 255 );
        histogram->SetMinIgnore( 0 );
        histogram->SetMaxIgnore( 20 );
        histogram->SetNumberOfMarkers( 4 );
        histogram->SetMarkerColor( 0, Qt::red );
        histogram->SetMarkerValue( 0, 10 );
        histogram->SetMarkerColor( 1, Qt::green );
        histogram->SetMarkerValue( 1, 30 );
        histogram->SetMarkerColor( 2, Qt::blue );
        histogram->SetMarkerValue( 2, 50 );
        histogram->SetMarkerColor( 3, Qt::yellow );
        histogram->SetMarkerValue( 3, 70 );

        histogram->resize( 600, 200 );

        a.setMainWidget( histogram );
        histogram->show();

        QApplication::setGlobalMouseTracking( true );

        return a.exec();
    } catch ( runtime_error& e ) {
        cerr << "failed with exception: " << e.what() << endl;
        exit( 1 );
    } catch ( exception& e ) {
        cerr << "failed with exception: " << e.what() << endl;
        exit( 1 );
    } catch (...) {
        cerr << "failed" << endl;
        exit( 1 );
    }


    exit( 0 );
}
Пример #21
0
VolumeCollection* ITKVolumeReader::read(const std::string &url)
    throw (tgt::CorruptedFileException, tgt::IOException, std::bad_alloc)
{
    VolumeURL origin(url);
    std::string fileName = origin.getPath();

    LINFO("Reading file " << fileName);

    //Get OutputInformation of an arbitrary reader to find out pixel type etc:
    typedef itk::Image<char,3> TestImageType; // pixel type doesn't matter for current purpose
    typedef itk::ImageFileReader<TestImageType> TestFileReaderType; // reader for testing a file
    TestFileReaderType::Pointer onefileReader = TestFileReaderType::New();
    onefileReader->SetFileName(fileName.c_str());
    try
    {
        onefileReader->GenerateOutputInformation();
    }
    catch(itk::ExceptionObject& excp)
    {
        throw tgt::CorruptedFileException("Failed to read OutputInformation! " + std::string(excp.GetDescription()), fileName);
    }

    // grab the ImageIO instance for the reader
    itk::ImageIOBase *imageIO = onefileReader->GetImageIO();

    unsigned int NumberOfDimensions =  imageIO->GetNumberOfDimensions();
    LINFO("Number of Dimensions: " << NumberOfDimensions);
    if(NumberOfDimensions != 3) {
        throw tgt::UnsupportedFormatException("Unsupported number of dimensions!");
    }

    // PixelType is SCALAR, RGB, RGBA, VECTOR, COVARIANTVECTOR, POINT, INDEX
    itk::ImageIOBase::IOPixelType pixelType = imageIO->GetPixelType();
    LINFO("PixelType: " << imageIO->GetPixelTypeAsString(pixelType));

    // IOComponentType is UCHAR, CHAR, USHORT, SHORT, UINT, INT, ULONG, LONG, FLOAT, DOUBLE
    itk::ImageIOBase::IOComponentType componentType = imageIO->GetComponentType();
    LINFO("ComponentType: " << imageIO->GetComponentTypeAsString(componentType));

    // NumberOfComponents is usually one, but for non-scalar pixel types, it can be anything
    unsigned int NumberOfComponents = imageIO->GetNumberOfComponents();
    LINFO("Number of Components: " << NumberOfComponents);
    if(NumberOfComponents != 1) {
        throw tgt::UnsupportedFormatException("Unsupported number of components!");
    }

    //-------Info we don't need here:---------------
    //unsigned dims[32];   // almost always no more than 4 dims, but ...
    //unsigned origin[32];
    double spacing[32];
    //std::vector<double> directions[32];
    for(unsigned i = 0; i < NumberOfDimensions && i < 32; i++)
    {
        //dims[i] = imageIO->GetDimensions(i);
        //origin[i] = imageIO->GetOrigin(i);
        spacing[i] = imageIO->GetSpacing(i);
        //directions[i] = imageIO->GetDirection(i);
    }

    Volume* dataset;
    switch(pixelType) {
        case itk::ImageIOBase::SCALAR:
            switch(componentType) {
                case itk::ImageIOBase::UCHAR:
                    dataset = readScalarVolume<uint8_t>(fileName);
                    break;
                case itk::ImageIOBase::CHAR:
                    dataset = readScalarVolume<int8_t>(fileName);
                    break;
                case itk::ImageIOBase::USHORT:
                    dataset = readScalarVolume<uint16_t>(fileName);
                    break;
                case itk::ImageIOBase::SHORT:
                    dataset = readScalarVolume<int16_t>(fileName);
                    break;
                case itk::ImageIOBase::UINT:
                    dataset = readScalarVolume<uint32_t>(fileName);
                    break;
                case itk::ImageIOBase::INT:
                    dataset = readScalarVolume<int32_t>(fileName);
                    break;
#ifndef WIN32
                case itk::ImageIOBase::ULONG:
                    dataset = readScalarVolume<uint64_t>(fileName);
                    break;
                case itk::ImageIOBase::LONG:
                    dataset = readScalarVolume<int64_t>(fileName);
                    break;
#endif
                case itk::ImageIOBase::FLOAT:
                    dataset = readScalarVolume<float>(fileName);
                    break;
                case itk::ImageIOBase::DOUBLE:
                    dataset = readScalarVolume<double>(fileName);
                    break;
                default:
                    throw tgt::UnsupportedFormatException("Unsupported component type!");
            }
            break;
        case itk::ImageIOBase::RGB:
        case itk::ImageIOBase::RGBA:
        case itk::ImageIOBase::VECTOR:
        case itk::ImageIOBase::COVARIANTVECTOR:
        case itk::ImageIOBase::POINT:
        default:
            throw tgt::UnsupportedFormatException("Unsupported pixel type!");
        return 0;
    }

    VolumeCollection* volumeCollection = new VolumeCollection();
    dataset->setOrigin(fileName);
    volumeCollection->add(dataset);

    return volumeCollection;
}
Пример #22
0
VolumeCollection* AnalyzeVolumeReader::readNifti(const std::string &fileName, bool standalone)
    throw (tgt::FileException, std::bad_alloc)
{
    LINFO("Loading nifti file " << fileName);

    std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary);
    if(!file) {
        throw tgt::FileNotFoundException("Failed to open file: ", fileName);
    }

    //file.seekg(0, std::ios::end);
    //int fileSize = file.tellg();
    //file.seekg(0, std::ios::beg);

    nifti_1_header header;
    if (!file.read((char*)&header, sizeof(header))) {
        throw tgt::CorruptedFileException("Failed to read header!", fileName);
    }

    file.close();

    bool bigEndian = false;
    //check if swap is necessary:
    if((header.dim[0] < 0) || (header.dim[0] > 15)) {
        bigEndian = true;
        header.swapEndianess();
    }

    if(header.sizeof_hdr != 348) {
        throw tgt::CorruptedFileException("Invalid header.sizeof_hdr", fileName);
    }

    if(!( (header.magic[0] == 'n') && (header.magic[2] == '1') && (header.magic[3] == 0) ))
        throw tgt::CorruptedFileException("Not a Nifti header!", fileName);

    if(header.magic[1] == '+') {
        if(!standalone)
            LWARNING("Tried to read standalone Nifti as hdr+img!");
        standalone = true;
    }
    else if(header.magic[1] == 'i') {
        if(!standalone)
            LWARNING("Tried to hdr+img Nifti as standalone!");
        standalone = false;
    }
    else
        throw tgt::CorruptedFileException("Not a Nifti header!", fileName);

    RawVolumeReader::ReadHints h;

    h.dimensions_.x = header.dim[1];
    h.dimensions_.y = header.dim[2];
    h.dimensions_.z = header.dim[3];
    LINFO("Resolution: " << h.dimensions_);

    if (hor(lessThanEqual(h.dimensions_, ivec3(0)))) {
        LERROR("Invalid resolution or resolution not specified: " << h.dimensions_);
        throw tgt::CorruptedFileException("error while reading data", fileName);
    }

    h.spacing_.x = header.pixdim[1];
    h.spacing_.y = header.pixdim[2];
    h.spacing_.z = header.pixdim[3];
    LINFO("Spacing: " << h.spacing_);

    LINFO("Datatype: " << header.datatype);

    //TODO: support more datatypes
    if(header.datatype > 128) {
        header.datatype -= 128;
        h.objectModel_ = "RGB";
    }
    else
        h.objectModel_ = "I";


    switch(header.datatype) {
        case DT_UNSIGNED_CHAR:
            h.format_ = "UCHAR";
            h.objectModel_ = "I";
            break;
        case DT_SIGNED_SHORT:
            h.format_ = "SHORT";
            h.objectModel_ = "I";
            break;
        case DT_SIGNED_INT:
            h.format_ = "INT";
            h.objectModel_ = "I";
            break;
        case DT_FLOAT:
            h.format_ = "FLOAT";
            h.objectModel_ = "I";
            break;
        case DT_DOUBLE:
            h.format_ = "DOUBLE";
            h.objectModel_ = "I";
            break;
        case DT_RGB:
            h.format_ = "UCHAR";
            h.objectModel_ = "RGB";
            break;
        case DT_RGBA32:         /* 4 byte RGBA (32 bits/voxel)  */
            h.format_ = "UCHAR";
            h.objectModel_ = "RGBA";
            break;
        case DT_INT8:           /* signed char (8 bits)         */
            h.format_ = "CHAR";
            h.objectModel_ = "I";
            break;
        case DT_UINT16:         /* unsigned short (16 bits)     */
            h.format_ = "USHORT";
            h.objectModel_ = "I";
            break;
        case DT_UINT32:         /* unsigned int (32 bits)       */
            h.format_ = "UINT";
            h.objectModel_ = "I";
            break;
        case DT_INT64:          /* long long (64 bits)          */
        case DT_UINT64:         /* unsigned long long (64 bits) */
        case DT_FLOAT128:       /* long double (128 bits)       */
        case DT_COMPLEX128:     /* double pair (128 bits)       */
        case DT_COMPLEX256:     /* long double pair (256 bits)  */
        case DT_ALL:
        case DT_COMPLEX:
        case 0: //DT_NONE/DT_UNKNOWN
        case DT_BINARY:
        default:
            throw tgt::UnsupportedFormatException("Unsupported datatype!");
    }

    if (header.intent_code == IC_INTENT_SYMMATRIX) {
        h.objectModel_ = "TENSOR_FUSION_LOW";
    }

    h.bigEndianByteOrder_ = bigEndian;

    //std::string objectType;
    //std::string gridType;
        //} else if (type == "ObjectType:") {
            //args >> objectType;
            //LDEBUG(type << " " << objectType);
        //} else if (type == "GridType:") {
            //args >> gridType;
            //LDEBUG(type << " " << gridType);
        //} else if (type == "BitsStored:") {
            //args >> h.bitsStored_;
            //LDEBUG(type << " " << h.bitsStored_);
        //} else if (type == "Unit:") {
            //args >> h.unit_;
            //LDEBUG(type << " " << h.unit_);

    if (standalone)
        h.headerskip_ = static_cast<uint16_t>(header.vox_offset);

    RawVolumeReader rawReader(getProgressBar());
    rawReader.setReadHints(h);

    VolumeCollection* volumeCollection = 0;
    if(standalone)
        volumeCollection = rawReader.read(fileName);
    else
        volumeCollection = rawReader.read(getRelatedImgFileName(fileName));

    if (!volumeCollection->empty()) {
        static_cast<VolumeHandle*>(volumeCollection->first())->setOrigin(VolumeOrigin(fileName));
        oldVolumePosition(static_cast<VolumeHandle*>(volumeCollection->first()));
    }

    return volumeCollection;
}
Пример #23
0
VolumeCollection* AnalyzeVolumeReader::readAnalyze(const std::string &fileName)
    throw (tgt::FileException, std::bad_alloc)
{
    LWARNING("Loading analyze file " << fileName);
    LWARNING("Related img file: " << getRelatedImgFileName(fileName));

    std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary);
    if(!file) {
        throw tgt::FileNotFoundException("Failed to open file: ", fileName);
    }

    file.seekg(0, std::ios::end);
    std::streamoff fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

    if(fileSize != 348)
        LWARNING("Filesize != 348");

    header_key header;
    if (!file.read((char*)&header, sizeof(header))) {
        throw tgt::CorruptedFileException("Failed to read header!", fileName);
    }

    image_dimension dimension;
    if (!file.read((char*)&dimension, sizeof(dimension))) {
        throw tgt::CorruptedFileException("Failed to read dimensions!", fileName);
    }

    data_history history;
    if (!file.read((char*)&history, sizeof(history))) {
        throw tgt::CorruptedFileException("Failed to read history!", fileName);
    }

    bool bigEndian = false;
    //check if swap is necessary:
    if((dimension.dim[0] < 0) || (dimension.dim[0] > 15)) {
        bigEndian = true;
        header.swapEndianess();
        dimension.swapEndianess();
        history.swapEndianess();
    }

    RawVolumeReader::ReadHints h;

    h.dimensions_.x = dimension.dim[1];
    h.dimensions_.y = dimension.dim[2];
    h.dimensions_.z = dimension.dim[3];
    LINFO("Resolution: " << h.dimensions_);

    if (hor(lessThanEqual(h.dimensions_, ivec3(0)))) {
        LERROR("Invalid resolution or resolution not specified: " << h.dimensions_);
        throw tgt::CorruptedFileException("error while reading data", fileName);
    }

    h.spacing_.x = dimension.pixdim[1];
    h.spacing_.y = dimension.pixdim[2];
    h.spacing_.z = dimension.pixdim[3];
    LINFO("Spacing: " << h.spacing_);

    LINFO("Datatype: " << dimension.datatype);

    switch(dimension.datatype) {
        case DT_UNSIGNED_CHAR:
            h.format_ = "UCHAR";
            h.objectModel_ = "I";
            break;
        case DT_SIGNED_SHORT:
            h.format_ = "SHORT";
            h.objectModel_ = "I";
            break;
        case DT_SIGNED_INT:
            h.format_ = "INT";
            h.objectModel_ = "I";
            break;
        case DT_FLOAT:
            h.format_ = "FLOAT";
            h.objectModel_ = "I";
            break;
        case DT_DOUBLE:
            h.format_ = "DOUBLE";
            h.objectModel_ = "I";
            break;
        case DT_RGB:
            h.format_ = "UCHAR";
            h.objectModel_ = "RGB";
            break;
        case DT_ALL:
        case DT_COMPLEX:
        case 0: //DT_NONE/DT_UNKNOWN
        case DT_BINARY:
        default:
            throw tgt::UnsupportedFormatException("Unsupported datatype!");
    }

    h.bigEndianByteOrder_ = bigEndian;

    std::string objectType;
    std::string gridType;

    RawVolumeReader rawReader(getProgressBar());
    rawReader.setReadHints(h);

    VolumeCollection* volumeCollection = rawReader.read(getRelatedImgFileName(fileName));

    if (!volumeCollection->empty()) {
        static_cast<VolumeHandle*>(volumeCollection->first())->setOrigin(VolumeOrigin(fileName));
        oldVolumePosition(static_cast<VolumeHandle*>(volumeCollection->first()));
    }

    return volumeCollection;
}
Пример #24
0
VolumeCollection* PVMVolumeReader::read(const std::string &url)
    throw (tgt::FileException, tgt::IOException, std::bad_alloc)
{
    VolumeOrigin origin(url);
    std::string fileName = origin.getPath();

    uint8_t* data;
    uint8_t* tmpData;

    unsigned int width, height, depth, components;
    float scalex, scaley, scalez;
    unsigned char *description;
    unsigned char *courtesy;
    unsigned char *parameter;
    unsigned char *comment;

    LINFO("Reading PVM volume " << fileName);

    /*
        TODO This subroutine returns an array created with malloc but it should
        be created with 'new[]' because this chunk of data will be deleted with 'delete[]'.
        This can cause hard to find errors.

        As a temporary workaround the data are copied over into a new array
        and the c-array is deleted with 'free'.
        Because of some c-pointer vodoo done in ddsbase.cpp free must be invoked
        after the use of all other returned pointers. (roland)
    */
    tmpData = readPVMvolume(const_cast<char*>(fileName.c_str()), getProgressBar(),
                            &width, &height, &depth, &components,
                            &scalex, &scaley, &scalez, &description, &courtesy,
                            &parameter, &comment);

    if (!tmpData) {
        LERROR("PVM Reading failed");
        return 0;
    }

    data = new uint8_t[width * height * depth * components];
    memcpy(data, tmpData, width * height * depth * components);

    Volume* dataset = 0;

    if (!data) {
        throw tgt::IOException();
    }
    else {
        LINFO("Size: " << width << " x " << height << " x " << depth);
        LINFO("Spacing: " << scalex << " x " << scaley << " x " << scalez);
        LINFO("Components: " << components);
        if (description)
            LINFO("Description: " << description);
        if (courtesy)
            LINFO("Courtesy: " << courtesy);
        if (parameter)
            LINFO("Parameter: " << parameter);
        if (comment)
            LINFO("Comment: " << comment);
        if (components == 1) {
            LINFO("Create 8 bit data set.");
            dataset = new VolumeUInt8(data, tgt::ivec3(width, height, depth),
                                      tgt::vec3(scalex, scaley, scalez));
        }
        else if (components == 2) {
            // the endianness conversion in ddsbase.cpp seem to be broken,
            // so we perform it here instead
            uint16_t* data16 = reinterpret_cast<uint16_t*>(data);
            int numElements = width * height * depth;
            uint16_t maxValue = 0;
            for (int i=0; i < numElements; i++) {
                endian_swap(data16[i]);
                if (data16[i] > maxValue)
                    maxValue = data16[i];
            }

            int bits;
            if (maxValue < 4096) {
                LINFO("Create 12 bit data set.");
                bits = 12;
            } else {
                LINFO("Create 16 bit data set.");
                bits = 16;
            }
            dataset = new VolumeUInt16((uint16_t*)data,
                                       tgt::ivec3(width, height, depth),
                                       tgt::vec3(scalex, scaley, scalez),
                                       tgt::mat4::identity,
                                       bits);

        }
        else LERROR("Bit depth not supported.");
    }

    // TODO now it is safe to free
    free(tmpData);

    VolumeCollection* volumeCollection = new VolumeCollection();
    if (dataset) {
        VolumeHandle* volumeHandle = new VolumeHandle(dataset, 0.0f);
        volumeHandle->setOrigin(VolumeOrigin(fileName));
        volumeCollection->add(volumeHandle);
    }

    return volumeCollection;
}