Пример #1
0
int CAEN_V814::Init()
{
  int status=0;
  ostringstream s; s << "[CAEN_V814]::[INFO]::++++++ CAEN V814 INIT ++++++";
  Log(s.str(),1);
  if (handle_<0)
    return ERR_CONF_NOT_FOUND;
  if (!IsConfigured())
    return ERR_CONF_NOT_FOUND;

  //Read Version to check connection
  WORD data=0;
  status |= CAENVME_ReadCycle(handle_,configuration_.baseAddress+CAEN_V814_VERSION_ADD,&data,CAEN_V814_ADDRESSMODE,CAEN_V814_DATAWIDTH);
  if (status)
    {
      s.str(""); s << "[CAEN_V814]::[ERROR]::Cannot open V814 board @0x" << std::hex << configuration_.baseAddress << std::dec << " " << status; 
      Log(s.str(),1);
      return ERR_OPEN;
    }    

  int version = (data&0xF000)>>12;
  int serial =  (data&0x0FFF);

  s.str(""); s << "[CAEN_V814]::[INFO]::Open V814 board @0x" << std::hex << configuration_.baseAddress << std::dec << " Version " << version << " S/N " << serial; 
  Log(s.str(),1);

  status |= SetPatternInhibit();

#ifdef CAEN_V814_VERBOSE
  s.str(""); s << "[CAEN_V814]::[INFO]::Pattern Mask has been set to " << configuration_.patternMask;
  Log(s.str(),1);
#endif
  status |= SetThreshold(-1);
#ifdef CAEN_V814_VERBOSE
  s.str(""); s << "[CAEN_V814]::[INFO]::All Thresholds have been set";
  Log(s.str(),1);
#endif

  for (unsigned i=0;i<CAEN_V814_CHANNELS;++i)
    if (configuration_.chThreshold[i]>0)
      {
	status |= SetThreshold(i);
#ifdef CAEN_V814_VERBOSE
	s.str(""); s << "[CAEN_V814]::[INFO]::Set specific threshold for Ch" <<i << " to 0x" << configuration_.chThreshold[i];
	Log(s.str(),1);
#endif
      }

  status|=SetMajorityThreshold(); // single 0x6 double 0x13 triple 0x1F

#ifdef CAEN_V814_VERBOSE
  s.str(""); s << "[CAEN_V814]::[INFO]::Majority Threshold has been set to 0x" << configuration_.majorityThreshold;
  Log(s.str(),1);
#endif

  status|=SetOutputWidth();

#ifdef CAEN_V814_VERBOSE
  s.str(""); s << "[CAEN_V814]::[INFO]::Output Width has been set to 0x" << configuration_.outputWidth;
  Log(s.str(),1);
#endif

  if (status)
    {
      s.str(""); s << "[CAEN_V814]::[ERROR]::Cannot config V814 @0x" << std::hex << configuration_.baseAddress << std::dec; 
      Log(s.str(),1);
      return ERR_OPEN;
    }    
  
  s.str(""); s << "[CAEN_V814]::[INFO]::++++++ CAEN V814 CONFIGURED ++++++";  
  Log(s.str(),1);
  
  return 0;
}
Пример #2
0
int main(int argc, char **argv) {
    args::ArgumentParser parser("Generates masks in stages.\n"
                                "Stage 1 - Otsu thresholding to generate binary mask\n"
                                "Stage 2 - RATs (optional)\n"
                                "Stage 3 - Hole filling (optional)\n"
                                "http://github.com/spinicist/QUIT");

    args::Positional<std::string> input_path(parser, "INPUT_FILE", "Input file");

    args::HelpFlag help(parser, "HELP", "Show this help menu", {'h', "help"});
    args::Flag     verbose(parser, "VERBOSE", "Print more information", {'v', "verbose"});
    args::ValueFlag<std::string> outarg(
        parser, "OUTPUT FILE", "Set output filename, default is input + _mask", {'o', "out"});
    args::ValueFlag<int> volume(
        parser, "VOLUME",
        "Choose volume to mask in multi-volume file. Default 1, -1 selects last volume",
        {'v', "volume"}, 0);
    args::Flag is_complex(parser, "COMPLEX", "Input data is complex, take magnitude first",
                          {'x', "complex"});
    args::ValueFlag<float> lower_threshold(
        parser, "LOWER THRESHOLD",
        "Specify lower intensity threshold for 1st stage, otherwise Otsu's method is used",
        {'l', "lower"}, 0.);
    args::ValueFlag<float> upper_threshold(
        parser, "UPPER THRESHOLD",
        "Specify upper intensity threshold for 1st stage, otherwise Otsu's method is used",
        {'u', "upper"}, std::numeric_limits<float>::infinity());
    args::ValueFlag<float> rats(
        parser, "RATS", "Perform the RATS step, argument is size threshold for connected component",
        {'r', "rats"}, 0.);
    args::ValueFlag<int> fillh_radius(
        parser, "FILL HOLES", "Fill holes in thresholded mask with radius N", {'F', "fillh"}, 0);

    QI::ParseArgs(parser, argc, argv, verbose);

    QI::SeriesF::Pointer vols = ITK_NULLPTR;
    if (is_complex) {
        vols = QI::ReadMagnitudeImage<QI::SeriesF>(QI::CheckPos(input_path), verbose);
    } else {
        vols = QI::ReadImage<QI::SeriesF>(QI::CheckPos(input_path), verbose);
    }

    std::string out_path;
    if (outarg.Get() == "") {
        out_path = QI::StripExt(input_path.Get()) + "_mask" + QI::OutExt();
    } else {
        out_path = outarg.Get();
    }

    // Extract one volume to process
    auto region = vols->GetLargestPossibleRegion();
    if (static_cast<size_t>(std::abs(volume.Get())) < region.GetSize()[3]) {
        int volume_to_get = (region.GetSize()[3] + volume.Get()) % region.GetSize()[3];
        QI::Log(verbose, "Masking volume {}...", volume_to_get);
        region.GetModifiableIndex()[3] = volume_to_get;
    } else {
        QI::Fail("Specified mask volume was invalid {} ", volume.Get());
    }
    region.GetModifiableSize()[3] = 0;
    auto vol                      = itk::ExtractImageFilter<QI::SeriesF, QI::VolumeF>::New();
    vol->SetExtractionRegion(region);
    vol->SetInput(vols);
    vol->SetDirectionCollapseToSubmatrix();
    vol->Update();
    QI::VolumeF::Pointer intensity_image = vol->GetOutput();
    intensity_image->DisconnectPipeline();

    /*
     *  Stage 1 - Otsu or Threshold
     */
    QI::VolumeI::Pointer mask_image = ITK_NULLPTR;
    if (lower_threshold || upper_threshold) {
        QI::Log(verbose, "Thresholding range: {}-{}", lower_threshold.Get(), upper_threshold.Get());
        mask_image =
            QI::ThresholdMask(intensity_image, lower_threshold.Get(), upper_threshold.Get());
    } else {
        QI::Log(verbose, "Generating Otsu mask");
        mask_image = QI::OtsuMask(intensity_image);
    }

    /*
     *  Stage 2 - RATS
     */
    if (rats) {
        typedef itk::BinaryBallStructuringElement<int, 3>                     TBall;
        typedef itk::BinaryErodeImageFilter<QI::VolumeI, QI::VolumeI, TBall>  TErode;
        typedef itk::BinaryDilateImageFilter<QI::VolumeI, QI::VolumeI, TBall> TDilate;
        float mask_volume  = std::numeric_limits<float>::infinity();
        float voxel_volume = QI::VoxelVolume(mask_image);
        QI::Log(verbose, "Voxel volume: {}", voxel_volume);
        int                  radius = 0;
        QI::VolumeI::Pointer mask_rats;
        while (mask_volume > rats.Get()) {
            radius++;
            TBall           ball;
            TBall::SizeType radii;
            radii.Fill(radius);
            ball.SetRadius(radii);
            ball.CreateStructuringElement();
            TErode::Pointer erode = TErode::New();
            erode->SetInput(mask_image);
            erode->SetForegroundValue(1);
            erode->SetBackgroundValue(0);
            erode->SetKernel(ball);
            erode->Update();
            std::vector<float> kept_sizes = QI::FindLabels(erode->GetOutput(), 0, 1, mask_rats);
            mask_volume                   = kept_sizes[0] * voxel_volume;
            auto dilate                   = TDilate::New();
            dilate->SetKernel(ball);
            dilate->SetInput(mask_rats);
            dilate->SetForegroundValue(1);
            dilate->SetBackgroundValue(0);
            dilate->Update();
            mask_rats = dilate->GetOutput();
            mask_rats->DisconnectPipeline();
            QI::Log(verbose, "Ran RATS iteration, radius = {} volume = {}", radius, mask_volume);
        }
        mask_image = mask_rats;
    }

    /*
     *  Stage 3 - Hole Filling
     */
    QI::VolumeI::Pointer finalMask = ITK_NULLPTR;
    if (fillh_radius) {
        QI::Log(verbose, "Filling holes");
        auto fillHoles = itk::VotingBinaryIterativeHoleFillingImageFilter<QI::VolumeI>::New();
        itk::VotingBinaryIterativeHoleFillingImageFilter<QI::VolumeI>::InputSizeType radius;
        radius.Fill(fillh_radius.Get());
        fillHoles->SetInput(mask_image);
        fillHoles->SetRadius(radius);
        fillHoles->SetMajorityThreshold(2); // Corresponds to (rad^3-1)/2 + 2 threshold
        fillHoles->SetBackgroundValue(0);
        fillHoles->SetForegroundValue(1);
        fillHoles->SetMaximumNumberOfIterations(3);
        fillHoles->Update();
        mask_image = fillHoles->GetOutput();
        mask_image->DisconnectPipeline();
    }

    QI::WriteImage(mask_image, out_path, verbose);
    QI::Log(verbose, "Finished.");
    return EXIT_SUCCESS;
}