/** Execute the algorithm. */ void LoadCalFile::exec() { std::string CalFilename = getPropertyValue("CalFilename"); std::string WorkspaceName = getPropertyValue("WorkspaceName"); bool MakeGroupingWorkspace = getProperty("MakeGroupingWorkspace"); bool MakeOffsetsWorkspace = getProperty("MakeOffsetsWorkspace"); bool MakeMaskWorkspace = getProperty("MakeMaskWorkspace"); if (WorkspaceName.empty()) throw std::invalid_argument("Must specify WorkspaceName."); Instrument_const_sptr inst = LoadCalFile::getInstrument3Ways(this); GroupingWorkspace_sptr groupWS; OffsetsWorkspace_sptr offsetsWS; MaskWorkspace_sptr maskWS; // Title of all workspaces = the file without path std::string title = Poco::Path(CalFilename).getFileName(); // Initialize all required workspaces. if (MakeGroupingWorkspace) { groupWS = GroupingWorkspace_sptr(new GroupingWorkspace(inst)); groupWS->setTitle(title); declareProperty(new WorkspaceProperty<GroupingWorkspace>("OutputGroupingWorkspace", WorkspaceName + "_group", Direction::Output), "Set the the output GroupingWorkspace, if any."); groupWS->mutableRun().addProperty("Filename",CalFilename); setProperty("OutputGroupingWorkspace", groupWS); } if (MakeOffsetsWorkspace) { offsetsWS = OffsetsWorkspace_sptr(new OffsetsWorkspace(inst)); offsetsWS->setTitle(title); declareProperty(new WorkspaceProperty<OffsetsWorkspace>("OutputOffsetsWorkspace", WorkspaceName + "_offsets", Direction::Output), "Set the the output OffsetsWorkspace, if any."); offsetsWS->mutableRun().addProperty("Filename",CalFilename); setProperty("OutputOffsetsWorkspace", offsetsWS); } if (MakeMaskWorkspace) { maskWS = MaskWorkspace_sptr(new MaskWorkspace(inst)); maskWS->setTitle(title); declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputMaskWorkspace", WorkspaceName + "_mask", Direction::Output), "Set the the output MaskWorkspace, if any."); maskWS->mutableRun().addProperty("Filename",CalFilename); setProperty("OutputMaskWorkspace", maskWS); } LoadCalFile::readCalFile(CalFilename, groupWS, offsetsWS, maskWS); }
/** Execute the ghost correction on all events in the input workspace **/ void GhostCorrection::exec() { // Get the input workspace this->inputW = getProperty("InputWorkspace"); //Load the grouping GroupingWorkspace_sptr groupWS = getProperty("GroupingWorkspace"); groupWS->makeDetectorIDToGroupMap(detId_to_group, nGroups); if (this->nGroups <= 0) throw std::runtime_error("The # of groups found in the Grouping file is 0."); // Now the offsets OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace"); //Make the X axis to bin to. MantidVecPtr XValues_new; const int64_t numbins = VectorHelper::createAxisFromRebinParams(getProperty("BinParams"), XValues_new.access()); //Prepare the binfinder class BinFinder binner( getProperty("BinParams") ); if (binner.lastBinIndex() != static_cast<int>(XValues_new.access().size()-1)) { std::stringstream msg; msg << "GhostCorrection: The binner found " << binner.lastBinIndex()+1 << " bins, but the X axis has " << XValues_new.access().size() << ". Try different binning parameters."; throw std::runtime_error(msg.str()); } //Create an output Workspace2D with group # of output spectra MatrixWorkspace_sptr outputW = WorkspaceFactory::Instance().create("Workspace2D", this->nGroups-1, numbins, numbins-1); WorkspaceFactory::Instance().initializeFromParent(inputW, outputW, true); //Set the X bins in the output WS. Workspace2D_sptr outputWS2D = boost::dynamic_pointer_cast<Workspace2D>(outputW); for (std::size_t i=0; i < outputWS2D->getNumberHistograms(); i++) outputWS2D->setX(i, XValues_new); //Prepare the maps you need input_detectorIDToWorkspaceIndexMap = inputW->getDetectorIDToWorkspaceIndexMap(true); //Load the ghostmapping file this->loadGhostMap( getProperty("GhostCorrectionFilename") ); //Initialize progress reporting. int64_t numsteps = 0; //count how many steps for (int64_t gr=1; gr < this->nGroups; ++gr) numsteps += this->groupedGhostMaps[gr]->size(); Progress prog(this, 0.0, 1.0, numsteps); //Set up the tof-to-d_spacing map for all pixel ids. this->tof_to_d = Mantid::Algorithms::AlignDetectors::calcTofToD_ConversionMap(inputW, offsetsWS); // Set the final unit that our output workspace will have outputW->getAxis(0)->unit() = UnitFactory::Instance().create("dSpacing"); //Go through the groups, starting at #1! PARALLEL_FOR2(inputW, outputW) for (int64_t gr=1; gr < this->nGroups; ++gr) { PARALLEL_START_INTERUPT_REGION //TODO: Convert between group # and workspace index. Sigh. //Groups normally start at 1 and so the workspace index will be one below that. int64_t outputWorkspaceIndex = gr-1; //Start by making sure the Y and E values are 0. MantidVec& Y = outputW->dataY(outputWorkspaceIndex); MantidVec& E = outputW->dataE(outputWorkspaceIndex); Y.assign(Y.size(), 0.0); E.assign(E.size(), 0.0); //Perform the GhostCorrection //Ok, this map has as keys the source workspace indices GhostSourcesMap * thisGroupsGhostMap = this->groupedGhostMaps[gr]; GhostSourcesMap::iterator it; for (it = thisGroupsGhostMap->begin(); it != thisGroupsGhostMap->end(); ++it) { //This workspace index is causing 16 ghosts in this group. int64_t inputWorkspaceIndex = it->first; int64_t inputDetectorID = it->second; //This is the events in the pixel CAUSING the ghost. const EventList & sourceEventList = inputW->getEventList(inputWorkspaceIndex); //Now get the actual vector of tofevents const std::vector<TofEvent>& events = sourceEventList.getEvents(); size_t numEvents = events.size(); //Go through all events. for (size_t i=0; i < numEvents; i++) { const TofEvent& event = events[i]; for (int64_t g=0; g < NUM_GHOSTS; g++) { //Find the ghost correction int64_t fileIndex = inputDetectorID * NUM_GHOSTS + g; GhostDestinationValue ghostVal = (*rawGhostMap)[fileIndex]; //Convert to d-spacing using the factor of the GHOST pixel id double d_spacing = event.tof() * (*tof_to_d)[ghostVal.pixelId]; //Find the bin for this d-spacing int64_t binIndex = binner.bin(d_spacing); if (binIndex >= 0) { //Slap it in the Y array for this group; use the weight. Y[binIndex] += ghostVal.weight; } } //for each ghost } //for each event //Report progress prog.report(); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Assign the workspace to the output workspace property setProperty("OutputWorkspace", outputW); }
/** Reads the calibration file. * * @param calFileName :: path to the old .cal file * @param groupWS :: optional, GroupingWorkspace to save. Will be 0 if not specified. * @param offsetsWS :: optional, OffsetsWorkspace to save. Will be 0.0 if not specified. * @param maskWS :: optional, masking-type workspace to save. Will be 1 (selected) if not specified. */ void SaveCalFile::saveCalFile(const std::string& calFileName, GroupingWorkspace_sptr groupWS, OffsetsWorkspace_sptr offsetsWS, MaskWorkspace_sptr maskWS) { Instrument_const_sptr inst; bool doGroup = false; if (groupWS) { doGroup = true; inst = groupWS->getInstrument(); } bool doOffsets = false; if (offsetsWS) { doOffsets = true; inst = offsetsWS->getInstrument(); } bool doMask = false; if (maskWS) { doMask = true; inst = maskWS->getInstrument(); if (!inst) g_log.warning() << "Mask workspace " << maskWS->name() << " has no instrument associated with." << "\n"; } g_log.information() << "Status: doGroup = " << doGroup << " doOffsets = " << doOffsets << " doMask = " << doMask << "\n"; if (!inst) throw std::invalid_argument("You must give at least one of the grouping, offsets or masking workspaces."); // Header of the file std::ofstream fout(calFileName.c_str()); fout <<"# Calibration file for instrument " << inst->getName() << " written on " << DateAndTime::getCurrentTime().toISO8601String() << ".\n"; fout <<"# Format: number UDET offset select group\n"; // Get all the detectors detid2det_map allDetectors; inst->getDetectors(allDetectors); int64_t number=0; detid2det_map::const_iterator it; for (it = allDetectors.begin(); it != allDetectors.end(); ++it) { detid_t detectorID = it->first; // Geometry::IDetector_const_sptr det = it->second; //Find the offset, if any double offset = 0.0; if (doOffsets) offset = offsetsWS->getValue(detectorID, 0.0); //Find the group, if any int64_t group = 1; if (doGroup) group = static_cast<int64_t>(groupWS->getValue(detectorID, 0.0)); // Find the selection, if any int selected = 1; if (doMask && (maskWS->isMasked(detectorID))) selected = 0; //if(group > 0) fout << std::fixed << std::setw(9) << number << std::fixed << std::setw(15) << detectorID << std::fixed << std::setprecision(7) << std::setw(15)<< offset << std::fixed << std::setw(8) << selected << std::fixed << std::setw(8) << group << "\n"; number++; } }
/** Reads the calibration file. * * @param calFileName :: path to the old .cal file * @param groupWS :: optional, GroupingWorkspace to fill. Must be initialized to the right instrument. * @param offsetsWS :: optional, OffsetsWorkspace to fill. Must be initialized to the right instrument. * @param maskWS :: optional, masking-type workspace to fill. Must be initialized to the right instrument. */ void LoadCalFile::readCalFile(const std::string& calFileName, GroupingWorkspace_sptr groupWS, OffsetsWorkspace_sptr offsetsWS, MaskWorkspace_sptr maskWS) { bool doGroup = bool(groupWS); bool doOffsets = bool(offsetsWS); bool doMask = bool(maskWS); bool hasUnmasked(false); bool hasGrouped(false); if (!doOffsets && !doGroup && !doMask) throw std::invalid_argument("You must give at least one of the grouping, offsets or masking workspaces."); std::ifstream grFile(calFileName.c_str()); if (!grFile) { throw std::runtime_error("Unable to open calibration file " + calFileName); } size_t numErrors = 0; detid2index_map detID_to_wi; if (doMask) { detID_to_wi = maskWS->getDetectorIDToWorkspaceIndexMap(); } // not all of these should be doubles, but to make reading work read as double then recast to int int n,udet,select,group; double n_d, udet_d, offset, select_d, group_d; std::string str; while(getline(grFile,str)) { if (str.empty() || str[0] == '#') continue; std::istringstream istr(str); // read in everything as double then cast as appropriate istr >> n_d >> udet_d >> offset >> select_d >> group_d; n = static_cast<int>(n_d); udet = static_cast<int>(udet_d); select = static_cast<int>(select_d); group = static_cast<int>(group_d); if (doOffsets) { if (offset <= -1.) // should never happen { std::stringstream msg; msg << "Encountered offset = " << offset << " at index " << n << " for udet = " << udet << ". Offsets must be greater than -1."; throw std::runtime_error(msg.str()); } try { offsetsWS->setValue(udet, offset); } catch (std::invalid_argument &) { numErrors++; } } if (doGroup) { try { groupWS->setValue(udet, double(group) ); if ((!hasGrouped) && (group > 0)) hasGrouped = true; } catch (std::invalid_argument &) { numErrors++; } } if (doMask) { detid2index_map::const_iterator it = detID_to_wi.find(udet); if (it != detID_to_wi.end()) { size_t wi = it->second; if (select <= 0) { // Not selected, then mask this detector maskWS->maskWorkspaceIndex(wi); maskWS->dataY(wi)[0] = 1.0; } else { // Selected, set the value to be 0 maskWS->dataY(wi)[0] = 0.0; if (!hasUnmasked) hasUnmasked = true; } } else { // Could not find the UDET. numErrors++; } } } // Warn about any errors if (numErrors > 0) Logger("LoadCalFile").warning() << numErrors << " errors (invalid Detector ID's) found when reading .cal file '" << calFileName << "'.\n"; if (doGroup && (!hasGrouped)) Logger("LoadCalFile").warning() << "'" << calFileName << "' has no spectra grouped\n"; if (doMask && (!hasUnmasked)) Logger("LoadCalFile").warning() << "'" << calFileName << "' masks all spectra\n"; }
/** Execute the algorithm. */ void LoadCalFile::exec() { std::string CalFilename = getPropertyValue("CalFilename"); std::string WorkspaceName = getPropertyValue("WorkspaceName"); bool MakeGroupingWorkspace = getProperty("MakeGroupingWorkspace"); bool MakeOffsetsWorkspace = getProperty("MakeOffsetsWorkspace"); bool MakeMaskWorkspace = getProperty("MakeMaskWorkspace"); if (WorkspaceName.empty()) throw std::invalid_argument("Must specify WorkspaceName."); Instrument_const_sptr inst = LoadCalFile::getInstrument3Ways(this); GroupingWorkspace_sptr groupWS; OffsetsWorkspace_sptr offsetsWS; MaskWorkspace_sptr maskWS; // Title of all workspaces = the file without path std::string title = Poco::Path(CalFilename).getFileName(); // Initialize all required workspaces. if (MakeGroupingWorkspace) { groupWS = GroupingWorkspace_sptr(new GroupingWorkspace(inst)); groupWS->setTitle(title); declareProperty(Kernel::make_unique<WorkspaceProperty<GroupingWorkspace>>( "OutputGroupingWorkspace", WorkspaceName + "_group", Direction::Output), "Set the the output GroupingWorkspace, if any."); groupWS->mutableRun().addProperty("Filename", CalFilename); setProperty("OutputGroupingWorkspace", groupWS); } if (MakeOffsetsWorkspace) { offsetsWS = OffsetsWorkspace_sptr(new OffsetsWorkspace(inst)); offsetsWS->setTitle(title); declareProperty(Kernel::make_unique<WorkspaceProperty<OffsetsWorkspace>>( "OutputOffsetsWorkspace", WorkspaceName + "_offsets", Direction::Output), "Set the the output OffsetsWorkspace, if any."); offsetsWS->mutableRun().addProperty("Filename", CalFilename); setProperty("OutputOffsetsWorkspace", offsetsWS); } if (MakeMaskWorkspace) { maskWS = MaskWorkspace_sptr(new MaskWorkspace(inst)); maskWS->setTitle(title); declareProperty( Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>( "OutputMaskWorkspace", WorkspaceName + "_mask", Direction::Output), "Set the the output MaskWorkspace, if any."); maskWS->mutableRun().addProperty("Filename", CalFilename); setProperty("OutputMaskWorkspace", maskWS); } LoadCalFile::readCalFile(CalFilename, groupWS, offsetsWS, maskWS); if (MakeOffsetsWorkspace) { auto alg = createChildAlgorithm("ConvertDiffCal"); alg->setProperty("OffsetsWorkspace", offsetsWS); alg->executeAsChildAlg(); ITableWorkspace_sptr calWS = alg->getProperty("OutputWorkspace"); calWS->setTitle(title); declareProperty( Kernel::make_unique<WorkspaceProperty<ITableWorkspace>>( "OutputCalWorkspace", WorkspaceName + "_cal", Direction::Output), "Set the output Diffraction Calibration workspace, if any."); setProperty("OutputCalWorkspace", calWS); } }