Beispiel #1
0
void getInfo ( void *obj, info_t *info_ ) {
	VirtualVolume *volume = (VirtualVolume *) obj;
	std::string fmt = volume->getPrintableFormat();

	info_->root_dir   = volume->getROOT_DIR();
	info_->VXL_V      = volume->getVXL_V();
	info_->VXL_H      = volume->getVXL_H();
	info_->VXL_D      = volume->getVXL_D();
	info_->ORG_V      = volume->getORG_V();
	info_->ORG_H      = volume->getORG_H();
	info_->ORG_D      = volume->getORG_D();
	info_->DIM_V      = volume->getDIM_V();
	info_->DIM_H      = volume->getDIM_H();
	info_->DIM_D      = volume->getDIM_D();
	info_->DIM_C      = volume->getDIM_C();
	info_->BYTESxCHAN = volume->getBYTESxCHAN();
	info_->n_active   = volume->getNACtiveChannels();
	info_->active     = volume->getActiveChannels();
	info_->DIM_T      = volume->getDIM_T();
	info_->t0         = volume->getT0();
	info_->t1         = volume->getT1();
}
Beispiel #2
0
//automatically called when current thread is started
void CImport::run()
{
    /**/itm::debug(itm::LEV1, 0, __itm__current__function__);

    try
    {
        timerIO.start();

        /********************* 1) IMPORTING CURRENT VOLUME ***********************
        PRECONDITIONS:
        reimport = true  ==> the volume cannot be directly imported (i.e., w/o the
        additional info provided by the user) or the user explicitly asked for re-
        importing the volume.
        reimport = false ==> the volume is directly importable
        *************************************************************************/
        /**/itm::debug(itm::LEV_MAX, strprintf("importing current volume at \"%s\"", path.c_str()).c_str(), __itm__current__function__);

        // skip nonmatching entries
        QDir dir(path.c_str());
        if( dir.dirName().toStdString().substr(0,3).compare(itm::RESOLUTION_PREFIX) != 0)
            throw RuntimeException(strprintf("\"%s\" is not a valid resolution: the name of the folder does not start with \"%s\"",
                                             path.c_str(), itm::RESOLUTION_PREFIX.c_str() ).c_str());

        if(reimport)
            volumes.push_back(VirtualVolume::instance(path.c_str(), format, AXS_1, AXS_2, AXS_3, VXL_1, VXL_2, VXL_3));
        else
            volumes.push_back(VirtualVolume::instance(path.c_str()));




        /********************* 2) IMPORTING OTHER VOLUMES ***********************
        Importing all the available resolutions within the current volume's
        parent directory.
        *************************************************************************/
        /**/itm::debug(itm::LEV_MAX, "Importing other volumes of the multiresolution octree", __itm__current__function__);
        /* -------------------- detect candidate volumes -----------------------*/
        /**/itm::debug(itm::LEV_MAX, "Detecting volumes that CAN be loaded (let us call them CANDIDATE volumes: the correspondent structures will be destroyed after this step)", __itm__current__function__);
        vector<VirtualVolume*> candidateVols;
        QDir curParentDir(path.c_str());
        curParentDir.cdUp();
        QStringList otherDirs = curParentDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
        for(int k=0; k<otherDirs.size(); k++)
        {
            string path_i = curParentDir.absolutePath().append("/").append(otherDirs.at(k).toLocal8Bit().constData()).toStdString();            
            QDir dir_i(path_i.c_str());

            // skip volumes[0]
            if(dir.dirName() == dir_i.dirName())
                continue;

            // skip nonmatching entries
            if(dir_i.dirName().toStdString().substr(0,3).compare(itm::RESOLUTION_PREFIX) != 0)
                continue;

            /**/itm::debug(itm::LEV_MAX, strprintf("Checking for loadable volume at \"%s\"", path_i.c_str()).c_str(), __itm__current__function__);
            if( !reimport && VirtualVolume::isDirectlyImportable( path_i.c_str()) )
                candidateVols.push_back(VirtualVolume::instance(path_i.c_str()));
            else
                volumes.push_back(VirtualVolume::instance(path_i.c_str(), volumes[0]->getPrintableFormat(),
                                  volumes[0]->getAXS_1(), volumes[0]->getAXS_2(), volumes[0]->getAXS_3(),
                                  volumes[0]->getVXL_1(), volumes[0]->getVXL_2(), volumes[0]->getVXL_3()));
        }
        /* -------------------- import candidate volumes ------------------------*/
        /**/itm::debug(itm::LEV_MAX, "Importing loadable volumes (previously checked)", __itm__current__function__);
        for(int k=0; k<candidateVols.size(); k++)
        {
            int ratio = iim::round(  pow((volumes[0]->getMVoxels() / candidateVols[k]->getMVoxels()),(1/3.0f))  );

             /**/itm::debug(itm::LEV_MAX, strprintf("Importing loadable volume at \"%s\"", candidateVols[k]->getROOT_DIR()).c_str(), __itm__current__function__);
            if( !reimport && VirtualVolume::isDirectlyImportable( candidateVols[k]->getROOT_DIR()) )
                volumes.push_back(VirtualVolume::instance(candidateVols[k]->getROOT_DIR()));
            else
                volumes.push_back(VirtualVolume::instance(candidateVols[k]->getROOT_DIR(),    candidateVols[k]->getPrintableFormat(),
                              volumes[0]->getAXS_1(),       volumes[0]->getAXS_2(),       volumes[0]->getAXS_3(),
                              volumes[0]->getVXL_1()*ratio, volumes[0]->getVXL_2()*ratio, volumes[0]->getVXL_3()*ratio));
        }
        /* -------------------- destroy candidate volumes -----------------------*/
        /**/itm::debug(itm::LEV_MAX, "Destroying candidate volumes", __itm__current__function__);
        for(int k=0; k<candidateVols.size(); k++)
            delete candidateVols[k];
        /* ------------- sort imported volumes by ascending size ---------------*/
        /**/itm::debug(itm::LEV_MAX, "Sorting volumes by ascending size", __itm__current__function__);
        std::sort(volumes.begin(), volumes.end(), sortVolumesAscendingSize);
        /* ---------------------- check imported volumes -----------------------*/
        if(volumes.size() < 2)
            throw RuntimeException(strprintf("%d resolution found at %s: at least two resolutions are needed for the multiresolution mode",
                                             volumes.size(), qPrintable(curParentDir.path()) ).c_str());
        for(int k=0; k<volumes.size()-1; k++)
        {
            if(volumes[k]->getPrintableFormat().compare( volumes[k+1]->getPrintableFormat() ) != 0)
                throw RuntimeException(strprintf("Volumes have different formats at \"%s\"", qPrintable(curParentDir.absolutePath())).c_str());
            if(volumes[k]->getDIM_T() != volumes[k+1]->getDIM_T())
                throw RuntimeException(strprintf("Volumes have different time frames at \"%s\"", qPrintable(curParentDir.absolutePath())).c_str());
        }



        /**************** 3) GENERATING / LOADING VOLUME 3D MAP *****************
        We generate once for all a volume map from lowest-resolution volume.
        *************************************************************************/
        string volMapPath = curParentDir.path().toStdString() + "/" + VMAP_BIN_FILE_NAME;
        if(hasVolumeMapToBeRegenerated(volMapPath.c_str(), "0.9.42", vmapTDimMax, volumes[0]->getDIM_T()) || reimport || regenerateVMap)
        {
            /**/itm::debug(itm::LEV_MAX, "Entering volume's map generation section", __itm__current__function__);

            // check that the lowest resolution does not exceed the maximum allowed size for the volume map
            VirtualVolume* lowestResVol = volumes[0];
            if(lowestResVol->getDIM_H() > vmapXDimMax ||
               lowestResVol->getDIM_V() > vmapYDimMax ||
               lowestResVol->getDIM_D() > vmapZDimMax)
                itm::warning("@TODO: resample along XYZ so as to match the volume map maximum size", __itm__current__function__);

            vmapXDim = lowestResVol->getDIM_H();
            vmapYDim = lowestResVol->getDIM_V();
            vmapZDim = lowestResVol->getDIM_D();
            vmapCDim = lowestResVol->getDIM_C();
            // if the number of time frames exceeds the maximum, we put only the first vmapTDimMax in the volume map
            vmapTDim = std::min(vmapTDimMax, lowestResVol->getDIM_T());

            // generate volume map
            lowestResVol->setActiveFrames(0, vmapTDimMax -1);
            vmapData = lowestResVol->loadSubvolume_to_UINT8();
            FILE *volMapBin = fopen(volMapPath.c_str(), "wb");
            if(!volMapBin)
                throw RuntimeException(strprintf("Cannot write volume map at \"%s\". Please check your write permissions.", volMapPath.c_str()).c_str());
            uint16 verstr_size = static_cast<uint16>(strlen(itm::version.c_str()) + 1);
            fwrite(&verstr_size, sizeof(uint16), 1, volMapBin);
            fwrite(itm::version.c_str(), verstr_size, 1, volMapBin);
            fwrite(&vmapTDim,  sizeof(uint32), 1, volMapBin);
            fwrite(&vmapCDim,  sizeof(uint32), 1, volMapBin);
            fwrite(&vmapYDim,  sizeof(uint32), 1, volMapBin);
            fwrite(&vmapXDim,  sizeof(uint32), 1, volMapBin);
            fwrite(&vmapZDim,  sizeof(uint32), 1, volMapBin);
            size_t vmapSize = ((size_t)vmapYDim)*vmapXDim*vmapZDim*vmapCDim*vmapTDim;
            fwrite(vmapData, vmapSize, 1, volMapBin);
            fclose(volMapBin);
        }
        else
        {
            /**/itm::debug(itm::LEV_MAX, "Entering volume's map loading section", __itm__current__function__);

            // load volume map
            FILE *volMapBin = fopen(volMapPath.c_str(), "rb");
            uint16 verstr_size;
            if(!volMapBin)
                throw RuntimeException(strprintf("Cannot read volume map at \"%s\". Please check your read permissions.", volMapPath.c_str()).c_str());
            if(!fread(&verstr_size, sizeof(uint16), 1, volMapBin))
                throw RuntimeException("Unable to read volume map file (<version_size> field). Please delete the volume map and re-open the volume.");
            char ver[1024];
            if(!fread(ver, verstr_size, 1, volMapBin))
                throw RuntimeException("Unable to read volume map file (<version> field). Please delete the volume map and re-open the volume.");
            if(fread(&vmapTDim, sizeof(uint32), 1, volMapBin) != 1)
                throw RuntimeException("Unable to read volume map file (<vmapTDim> field). Please delete the volume map and re-open the volume.");
            if(fread(&vmapCDim, sizeof(uint32), 1, volMapBin) != 1)
                throw RuntimeException("Unable to read volume map file (<vmapCDim> field). Please delete the volume map and re-open the volume.");
            if(fread(&vmapYDim, sizeof(uint32), 1, volMapBin) != 1)
                throw RuntimeException("Unable to read volume map file (<vmapYDim> field). Please delete the volume map and re-open the volume.");
            if(fread(&vmapXDim,  sizeof(uint32), 1, volMapBin)!= 1)
                throw RuntimeException("Unable to read volume map file (<vmapXDim> field). Please delete the volume map and re-open the volume.");
            if(fread(&vmapZDim,  sizeof(uint32), 1, volMapBin)!= 1)
                throw RuntimeException("Unable to read volume map file (<vmapZDim> field). Please delete the volume map and re-open the volume.");
            size_t vmapSize = ((size_t)vmapYDim)*vmapXDim*vmapZDim*vmapCDim*vmapTDim;
            vmapData = new uint8[vmapSize];
            if(fread(vmapData, vmapSize, 1, volMapBin) != 1)
                throw RuntimeException("Unable to read volume map file (<vmapData> field). Please delete the volume map and re-open the volume.");
            fclose(volMapBin);


            //--- Alessandro 29/09/2013: checking that the loaded vmap corresponds to one of the loaded volumes
//            /**/itm::debug(itm::LEV_MAX, "checking that the loaded vmap corresponds to one of the loaded volumes", __itm__current__function__);
//            bool check_passed = false;
//            for(int i=0; i<volumes.size() && !check_passed; i++)
//                if(volumes[i]->getDIM_V() == vmapYDim  &&
//                   volumes[i]->getDIM_H() == vmapXDim  &&
//                   volumes[i]->getDIM_D() == vmapZDim  &&
//                   volumes[i]->getDIM_C() == vmapCDim)
//                    check_passed = true;
//            if(!check_passed)
//                throw RuntimeException(QString("Volume map stored at \"").append(volMapPath.c_str()).append("\" does not correspond to any of the loaded resolutions. Please delete or regenerate the volume map.").toStdString().c_str());

        }

        //everything went OK
        emit sendOperationOutcome(0, timerIO.elapsed());

        /**/itm::debug(itm::LEV1, "EOF", __itm__current__function__);
    }
    catch( iim::IOException& exception)  {reset(); emit sendOperationOutcome(new RuntimeException(exception.what()));}
    catch( iom::exception& exception)    {reset(); emit sendOperationOutcome(new RuntimeException(exception.what()));}
    catch( RuntimeException& exception)  {reset(); emit sendOperationOutcome(new RuntimeException(exception.what()));}
    catch(const char* error)             {reset(); emit sendOperationOutcome(new RuntimeException(error));}
    catch(...)                           {reset(); emit sendOperationOutcome(new RuntimeException("Unknown error occurred"));}
}
Beispiel #3
0
//automatically called when current thread is started
void CVolume::run()
{
    /**/tf::debug(tf::LEV1, 0, __itm__current__function__);

    try
    {
        VirtualVolume* volume = CImport::instance()->getVolume(voiResIndex);

        //---- Alessandro 2013-04-17: if VOI exceeds limits it is automatically adjusted. This is very useful in the cases the user is zooming-in
        //around peripheral regions
        voiV0 = voiV0 >=0                   ? voiV0 : 0;
        voiV1 = voiV1 <= volume->getDIM_V() ? voiV1 : volume->getDIM_V();
        voiH0 = voiH0 >=0                   ? voiH0 : 0;
        voiH1 = voiH1 <= volume->getDIM_H() ? voiH1 : volume->getDIM_H();
        voiD0 = voiD0 >=0                   ? voiD0 : 0;
        voiD1 = voiD1 <= volume->getDIM_D() ? voiD1 : volume->getDIM_D();
//        voiT0 = voiT0 >=0                   ? voiT0 : 0;
//        voiT1 = voiT1 <  volume->getDIM_T() ? voiT1 : volume->getDIM_T()-1;

        // check subvolume interval
        if(voiV1 - voiV0 <=0 || voiH1 - voiH0 <=0 || voiD1 - voiD0 <=0 || voiT1 - voiT0 <0)           
            throw RuntimeException(strprintf("Invalid subvolume intervals inserted: X=[%d, %d), Y=[%d, %d), Z=[%d, %d), T=[%d, %d]",
                                             voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiT0, voiT1));

        // check destination
        /**/tf::debug(tf::LEV2, "Check destination", __itm__current__function__);
        CViewer* destination = dynamic_cast<CViewer*>(source);
        if(!destination)
            throw RuntimeException("Destination type not supported");
        /**/tf::debug(tf::LEV2, strprintf("destination registered as \"%s\"", destination->title.c_str()).c_str(), __itm__current__function__);

        //checking for an imported volume
        if(volume)
        {
            if(streamingSteps == 1)
            {
                // 5D data with instant visualization of selected frame
                if(voiT0 != voiT1 && cur_t != -1)
                {
                    // load selected frame
                    QElapsedTimer timerIO;
                    timerIO.start();
                    volume->setActiveFrames(cur_t, cur_t);
                    /**/tf::debug(tf::LEV3, "load selected time frame", __itm__current__function__);
                    uint8* voiData = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1);
                    qint64 elapsedTime = timerIO.elapsed();


                    // wait for GUI thread to update graphics
                    /**/tf::debug(tf::LEV3, "Waiting for updateGraphicsInProgress mutex", __itm__current__function__);
                    /**/ updateGraphicsInProgress.lock();
                    /**/tf::debug(tf::LEV3, "Access granted from updateGraphicsInProgress mutex", __itm__current__function__);


                    // send data
                    integer_array data_s = make_vector<int>() << voiH0        << voiV0        << voiD0        << 0                            << cur_t;
                    integer_array data_c = make_vector<int>() << voiH1-voiH0  << voiV1-voiV0  << voiD1-voiD0  << volume->getNACtiveChannels() << 1;
                    emit sendData(voiData, data_s, data_c, source, false, 0, elapsedTime,
                                strprintf("Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d), T=[%d, %d] loaded from res %d",
                                voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, cur_t, cur_t, voiResIndex).c_str());

                    // unlock updateGraphicsInProgress mutex
                    /**/tf::debug(tf::LEV3, strprintf("updateGraphicsInProgress.unlock()").c_str(), __itm__current__function__);
                    /**/ updateGraphicsInProgress.unlock();
                }
                {
                    // load data
                    QElapsedTimer timerIO;
                    timerIO.start();
                    volume->setActiveFrames(voiT0, voiT1);
                    /**/tf::debug(tf::LEV3, "load data", __itm__current__function__);
                    uint8* voiData = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1);
                    qint64 elapsedTime = timerIO.elapsed();


                    // wait for GUI thread to update graphics
                    /**/tf::debug(tf::LEV3, "Waiting for updateGraphicsInProgress mutex", __itm__current__function__);
                    /**/ updateGraphicsInProgress.lock();
                    /**/tf::debug(tf::LEV3, "Access granted from updateGraphicsInProgress mutex", __itm__current__function__);


                    // send data
                    integer_array data_s = make_vector<int>() << voiH0        << voiV0        << voiD0        << 0                            << voiT0;
                    integer_array data_c = make_vector<int>() << voiH1-voiH0  << voiV1-voiV0  << voiD1-voiD0  << volume->getNACtiveChannels() << voiT1-voiT0+1;
                    emit sendData(voiData, data_s, data_c, source, true, 0, elapsedTime,
                                strprintf("Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d), T=[%d, %d] loaded from res %d",
                                voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiT0, voiT1, voiResIndex).c_str());
                    /**/tf::debug(tf::LEV3, "sendData signal emitted", __itm__current__function__);

                    // unlock updateGraphicsInProgress mutex
                    /**/tf::debug(tf::LEV3, strprintf("updateGraphicsInProgress.unlock()").c_str(), __itm__current__function__);
                    /**/ updateGraphicsInProgress.unlock();
                }
            }
            else
            {
                throw RuntimeException("Streaming != 1 has been temporarily disabled. Please contact the developer.");
//                    // precondition checks
//                    if(!buffer)
//                        throw RuntimeException("Buffer not initialized");
//                    CViewer* destination = dynamic_cast<CViewer*>(source);
//                    if(!destination)
//                        throw RuntimeException("Streaming not yet supported for this type of destination");
//                    if(streamingSteps != 2)
//                        throw RuntimeException("Only streaming steps = 2 supported for 5D data");

//                    for (int step = 1; step <= streamingSteps; step++)
//                    {
//                        // load current selected frame
//                        /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: loading data", step).c_str(), __itm__current__function__);
//                        volume->setActiveFrames(step == 1 ? cur_t : voiT0, step == 1 ? cur_t : voiT1);
//                        QElapsedTimer timerIO;
//                        timerIO.start();
//                        uint8* data = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1);
//                        qint64 elapsedTime = timerIO.elapsed();

//                        // copy frame to buffer ( ** CRITICAL SECTION ** )
//                        /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: waiting for buffer mutex", step).c_str(), __itm__current__function__);
//                        /**/ bufferMutex.lock();
//                        /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: access granted on buffer mutex", step).c_str(), __itm__current__function__);
//                        uint32 buf_dims[5]      = {voiH1-voiH0, voiV1-voiV0, voiD1-voiD0, volume->getDIM_C(), voiT1 - voiT0 +1};
//                        uint32 buf_offset[5]    = {0,           0,           0,           0,                            cur_t-voiT0};
//                        uint32 cur_t_dims[5]    = {voiH1-voiH0, voiV1-voiV0, voiD1-voiD0, volume->getDIM_C(), 1};
//                        uint32 cur_t_offset[5]  = {0,           0,           0,           0,                            0};
//                        uint32 cur_t_count[5]   = {voiH1-voiH0, voiV1-voiV0, voiD1-voiD0, volume->getDIM_C(), 1};
//                        CViewer::copyVOI(cur_t_data, cur_t_dims, cur_t_offset, cur_t_count, buffer, buf_dims, buf_offset);
//                        delete[] cur_t_data;
//                        /**/ bufferMutex.unlock();
//                        /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: unlocked buffer mutex", step).c_str(), __itm__current__function__);


//                        // wait GUI thread to complete update graphics
//                        /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: waiting for updateGraphicsInProgress mutex", step).c_str(), __itm__current__function__);
//                        /**/ destination->updateGraphicsInProgress.lock();
//                        /**/ destination->updateGraphicsInProgress.unlock();
//                        /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: unlocked updateGraphicsInProgress mutex", step).c_str(), __itm__current__function__);

//                        // send data to GUI thread
//                        finished = false;
//                        /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: sendOperationOutcome", step).c_str(), __itm__current__function__);
//                        sprintf(msg, "Streaming %d/%d: Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d) loaded from res %d",
//                                1, 2, voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiResIndex);
//                        emit sendOperationOutcome(buffer, 0, destination, elapsedTime, msg, 1);
//                    }









//                    // load current selected frame
//                    /**/tf::debug(tf::LEV3, "Time step 1/2: loading data", __itm__current__function__);
//                    volume->setActiveFrames(cur_t, cur_t);
//                    QElapsedTimer timerIO;
//                    timerIO.start();
//                    uint8* cur_t_data = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1);
//                    qint64 elapsedTime = timerIO.elapsed();


//                    /**/tf::debug(tf::LEV3, "Time step 2/2: waiting for buffer mutex", __itm__current__function__);
//                    /**/ bufferMutex.lock();
//                    /**/tf::debug(tf::LEV3, "Time step 2/2: access granted on buffer mutex", __itm__current__function__);
//                    timerIO.start();
//                    volume->setActiveFrames(voiT0 + (voiT1-voiT0)/2, voiT1);
//                    /**/tf::debug(tf::LEV3, "Time step 2/2: loading data", __itm__current__function__);
//                    buffer = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1);
//                    elapsedTime = timerIO.elapsed();
//                    /**/ bufferMutex.unlock();
//                    /**/tf::debug(tf::LEV3, "Time step 2/2: unlocked buffer mutex", __itm__current__function__);

//                    sprintf(msg, "Streaming %d/%d: Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d) loaded from res %d",
//                            2, 2, voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiResIndex);

//                    /**/tf::debug(tf::LEV3, "Time step 1/2: waiting for updateGraphicsInProgress mutex", __itm__current__function__);
//                    /**/ destination->updateGraphicsInProgress.lock();
//                    /**/ destination->updateGraphicsInProgress.unlock();
//                    /**/tf::debug(tf::LEV3, "Time step 1/2: unlocked updateGraphicsInProgress mutex", __itm__current__function__);

//                    finished = true;
//                    /**/tf::debug(tf::LEV3, "Time step 1/2: sendOperationOutcome", __itm__current__function__);
//                    emit sendOperationOutcome(buffer, 0, destination, elapsedTime, msg, 2);


//            //checking preconditions
//            TiledVolume* vaa3D_volume_RGB = dynamic_cast<TiledVolume*>(volume);
//            TiledMCVolume* vaa3D_volume_4D= dynamic_cast<TiledMCVolume*>(volume);
//            if(!vaa3D_volume_RGB && !vaa3D_volume_4D)
//                throw RuntimeException("Streaming not yet supported for the current format. Please restart the plugin.");
//            if(!buffer)
//                throw RuntimeException("Buffer not initialized");
//            CViewer* destination = dynamic_cast<CViewer*>(source);
//            if(!destination)
//                throw RuntimeException("Streaming not yet supported for this type of destination");

//            //reading/writing from/to the same buffer with MUTEX (see Producer-Consumer problem)
//            /**/tf::debug(tf::LEV3, "Calling streamedLoadSubvolume_open", __itm__current__function__);
//            void *stream_descr = 0;
//            if(vaa3D_volume_RGB)
//                stream_descr = vaa3D_volume_RGB->streamedLoadSubvolume_open(streamingSteps, buffer, voiV0, voiV1, voiH0, voiH1, voiD0, voiD1);
//            else
//                stream_descr = vaa3D_volume_4D->streamedLoadSubvolume_open(streamingSteps, buffer, voiV0, voiV1, voiH0, voiH1, voiD0, voiD1);
//            for (int currentStep = 1; currentStep <= streamingSteps; currentStep++)
//            {

//                /**/tf::debug(tf::LEV3, "Waiting for buffer mutex", __itm__current__function__);
//                /**/ bufferMutex.lock();
//                /**/tf::debug(tf::LEV3, "Access granted to buffer mutex, locking", __itm__current__function__);
//                QElapsedTimer timerIO;
//                timerIO.start();
//                if(vaa3D_volume_RGB)
//                    buffer = vaa3D_volume_RGB->streamedLoadSubvolume_dostep(stream_descr);
//                else if(vaa3D_volume_4D)
//                    buffer = vaa3D_volume_4D->streamedLoadSubvolume_dostep(stream_descr);
//                qint64 elapsedTime = timerIO.elapsed();
//                /**/ bufferMutex.unlock();
//                /**/tf::debug(tf::LEV3, "Unlocked buffer mutex", __itm__current__function__);

//                sprintf(msg, "Streaming %d/%d: Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d) loaded from res %d",
//                        currentStep, streamingSteps, voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiResIndex);

//                /**/tf::debug(tf::LEV3, "Waiting for updateGraphicsInProgress mutex", __itm__current__function__);
//                /**/ destination->updateGraphicsInProgress.lock();
//                /**/ destination->updateGraphicsInProgress.unlock();
//                /**/tf::debug(tf::LEV3, "Unlocked updateGraphicsInProgress mutex", __itm__current__function__);


//                finished = currentStep == streamingSteps;

//                if(finished)
//                {
//                    /**/tf::debug(tf::LEV3, "Calling streamedLoadSubvolume_close", __itm__current__function__);
//                    if(vaa3D_volume_RGB)
//                        buffer = vaa3D_volume_RGB->streamedLoadSubvolume_close(stream_descr);
//                    else if(vaa3D_volume_4D)
//                        buffer = vaa3D_volume_4D->streamedLoadSubvolume_close(stream_descr);
//                }

//                /**/tf::debug(tf::LEV3, strprintf("sendOperationOutcome, step %d", currentStep).c_str(), __itm__current__function__);
//                emit sendOperationOutcome(buffer, 0, destination, elapsedTime, msg, currentStep);
            }
        }
        else
            throw RuntimeException("No volume has been imported yet.");

        /**/tf::debug(tf::LEV1, "EOF", __itm__current__function__);
    }
    catch( iim::IOException& exception)
    {
        // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex
        CViewer* dest = dynamic_cast<CViewer*>(source);
        /**/ updateGraphicsInProgress.lock();
        reset();
        //bufferMutex.unlock();
        tf::warning(exception.what(), "CVolume");
        /**/ updateGraphicsInProgress.unlock();

        emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(exception.what()), 0, "");
    }
    catch( iom::exception& exception)
    {
        // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex
        CViewer* dest = dynamic_cast<CViewer*>(source);
        /**/ updateGraphicsInProgress.lock();
        reset();
        //bufferMutex.unlock();
        tf::warning(exception.what(), "CVolume");
        /**/ updateGraphicsInProgress.unlock();

        emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(exception.what()), 0, "");
    }
    catch( RuntimeException& exception)
    {
        // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex
        CViewer* dest = dynamic_cast<CViewer*>(source);
        /**/ updateGraphicsInProgress.lock();
        reset();
        //bufferMutex.unlock();
        tf::warning(exception.what(), "CVolume");
        /**/ updateGraphicsInProgress.unlock();

        emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(exception.what()), 0, "");
    }
    catch(const char* error)
    {
        // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex
        CViewer* dest = dynamic_cast<CViewer*>(source);
        /**/ updateGraphicsInProgress.lock();
        reset();
        //bufferMutex.unlock();
        tf::warning(error, "CVolume");
        /**/ updateGraphicsInProgress.unlock();

        emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(error), 0, "");
    }
    catch(...)
    {
        // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex
        CViewer* dest = dynamic_cast<CViewer*>(source);
        /**/ updateGraphicsInProgress.lock();
        reset();
        //bufferMutex.unlock();
        tf::warning("Unknown error occurred", "CVolume");
        /**/ updateGraphicsInProgress.unlock();

        emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException("Unknown error occurred"), 0, "");
    }
}