示例#1
0
void ProgXrayImport::readGeoInfo(const FileName &fn, MDRow &rowGeo) const
{
    double tiltAngle;

    switch (dSource)
    {
    case MISTRAL:
        tiltAngle = dMi(anglesArray, fn.getPrefixNumber()-1);
        break;
    case BESSY:
    case GENERIC:
        {
            FileName fnBase = fn.withoutExtension();
            std::ifstream fhPosition;
            fhPosition.open((fnBase+"-positions.txt").c_str());
            if (!fhPosition)
                REPORT_ERROR(ERR_IO_NOTEXIST,fnBase+"-positions.txt");
            int itemsFound=0;
            std::string line;
            std::vector<std::string> tokens;
            while (!fhPosition.eof())
            {
                getline(fhPosition,line);
                splitString(line," ",tokens);
                if (tokens[0]=="xm:sample:rx")
                {
                    tiltAngle=textToFloat(tokens[1]);
                    itemsFound++;
                }
                if (itemsFound==1)
                    break;
            }
            fhPosition.close();
            if (itemsFound!=1)
                REPORT_ERROR(ERR_VALUE_EMPTY,(std::string)"Cannot find tilt angle in "+
                             fnBase+"-positions.txt");
        }
        break;
    }

    rowGeo.setValue(MDL_ANGLE_TILT, tiltAngle);
}
示例#2
0
void ProgXrayImport::getFlatfield(const FileName &fnFFinput,
                                  Image<double> &Iavg)
{

    // Process the flatfield images


    MultidimArray<double> &mdaIavg = Iavg();

    Matrix1D<double> expTimeArray, cBeamArray, slitWidthArray; // Local vectors

    DataSource ldSource = dSource;

    // Checking if fnFFinput is a single file to obtain the flatfield avg from
    if (extFlat && isImage(fnFFinput))
    {
        fMD.read(fnFFinput);
        ldSource = NONE;
    }
    else
    {
        switch (ldSource)
        {
        case MISTRAL:
            if (!H5File.checkDataset(fnFFinput.getBlockName().c_str()))
                break;
            {
                fMD.read(fnFFinput);
                H5File.getDataset("NXtomo/instrument/bright_field/ExpTimes", expTimeArray, false);
                H5File.getDataset("NXtomo/instrument/bright_field/current", cBeamArray, false);

                // If expTime is empty or only one single value in nexus file then we fill with 1
                if (expTimeArray.size() < 2)
                {
                    reportWarning("Input file does not contains flatfields' exposition time information.");
                    expTimeArray.initConstant(fMD.size(), 1.);
                }
                // If current is empty or only one single value in nexus file then we fill with 1
                if (cBeamArray.size() < 2)
                {
                    reportWarning("Input file does not contains flatfields' current beam information.");
                    cBeamArray.initConstant(fMD.size(), 1.);
                }

            }

            // Since Alba does not provide slit width, we set to ones
            slitWidthArray.initConstant(fMD.size(), 1.);

            break;
        case BESSY:
            {
                size_t objId;

                for (size_t i = fIni; i <= fEnd; ++i)
                {
                    objId = fMD.addObject();
                    fMD.setValue(MDL_IMAGE, fnFFinput + formatString("/img%d.spe", i), objId);
                }
                break;
            }
        case GENERIC:
            {
                // Get Darkfield
                std::cout << "Getting darkfield from "+fnFFinput << " ..." << std::endl;
                getDarkfield(fnFFinput, IavgDark);
                if (darkFix)
                    IavgDark.write(fnRoot+"_"+fnFFinput.removeDirectories()+"_darkfield.xmp");

                std::vector<FileName> listDir;
                fnFFinput.getFiles(listDir);
                size_t objId;

                for (size_t i = 0; i < listDir.size(); ++i)
                {
                    if (!listDir[i].hasImageExtension())
                        continue;
                    objId = fMD.addObject();
                    fMD.setValue(MDL_IMAGE, fnFFinput+"/"+listDir[i], objId);
                }
            }
            break;
        }
    }

    if ( fMD.size() == 0 )
    {
        reportWarning("XrayImport::getFlatfield: No images to process");
        return;
    }

    ImageInfo imFFInfo;

    getImageInfo(fMD, imFFInfo);

    if ( (imFFInfo.adim.xdim != imgInfo.adim.xdim) || (imFFInfo.adim.ydim != imgInfo.adim.ydim) )
    {
        reportWarning(formatString("XrayImport:: Flatfield images size %dx%d different from Tomogram images size %dx%d",
                                   imFFInfo.adim.xdim,imFFInfo.adim.ydim,imgInfo.adim.xdim,imgInfo.adim.ydim));
        std::cout << "Setting crop values to fit the smallest dimensions." <<std::endl;

        // This shift in the crop sizes is exclusive of Mistral data
        cropSizeXi = (imgInfo.adim.xdim - std::min(imgInfo.adim.xdim-cropSizeX*2, imFFInfo.adim.xdim))/2 + 1;
        cropSizeYi = (imgInfo.adim.ydim - std::min(imgInfo.adim.ydim-cropSizeY*2, imFFInfo.adim.ydim))/2 + 1;
        cropSizeXe = cropSizeXi - 2;
        cropSizeYe = cropSizeYi - 2;
    }

    int cropX = (imFFInfo.adim.xdim - (imgInfo.adim.xdim-cropSizeXi-cropSizeXe))/2;// - 1;
    int cropY = (imFFInfo.adim.ydim - (imgInfo.adim.ydim-cropSizeYi-cropSizeYe))/2;// - 1;


    int N  = 0;
    Image<double> Iaux;
    FileName fnImg;

    FOR_ALL_OBJECTS_IN_METADATA(fMD)
    {
        fMD.getValue(MDL_IMAGE, fnImg, __iter.objId);

        readAndCrop(fnImg, Iaux, cropX, cropY);


        if ( darkFix )
        {
            Iaux() -= IavgDark();
            forcePositive(Iaux());
        }

        double currentBeam = 1;
        double expTime = 1;
        double slitWidth = 1;

        switch (ldSource)
        {
        case MISTRAL:
            {
                size_t idx = fnImg.getPrefixNumber();
                currentBeam = dMi(cBeamArray, idx-1);
                expTime = dMi(expTimeArray, idx-1);
                slitWidth = dMi(slitWidthArray, idx-1);
            }
            break;
        case BESSY:
        case GENERIC:
            readCorrectionInfo(fnImg, currentBeam, expTime, slitWidth);
            break;
        default:
            break;
        }

        Iaux() *= 1.0/(currentBeam*expTime*slitWidth);

        if ( N == 0 )
            mdaIavg = Iaux();
        else
            mdaIavg += Iaux();
        N++;
    }

    darkFix = false; // We reset just in case there is no dark field for tomo images

    mdaIavg*=1.0/N;

    /* Create a mask with zero valued pixels to apply boundaries median filter
     * to avoid dividing by zero when normalizing */

    MultidimArray<char> &mdaMask = MULTIDIM_ARRAY(bpMask);

    if ( !fnBPMask.empty() && !mdaIavg.sameShape(mdaMask) )
        REPORT_ERROR(ERR_MULTIDIM_SIZE, "XrayImport: Mask size does not match flat fields size.");

    if (BPFactor > 0)
    {
        double  avg, std;
        mdaIavg.computeAvgStdev(avg, std);
        mdaMask.resize(mdaIavg, false);

        double th = avg - std*BPFactor;
        FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mdaMask)
        dAi(mdaMask, n) = dAi(mdaIavg, n) < th;
    }
    else if (fnBPMask.empty())
        mdaIavg.equal(0,mdaMask);

    MultidimArray<char> mask = mdaMask;
    boundMedianFilter(mdaIavg,mask);
}