void CalculateDIFC::calculate() { Instrument_const_sptr instrument = m_inputWS->getInstrument(); SpecialWorkspace2D_sptr localWS = boost::dynamic_pointer_cast<SpecialWorkspace2D>(m_outputWS); double l1; Kernel::V3D beamline, samplePos; double beamline_norm; instrument->getInstrumentParameters(l1, beamline, beamline_norm, samplePos); // To get all the detector ID's detid2det_map allDetectors; instrument->getDetectors(allDetectors); // Now go through all detid2det_map::const_iterator it = allDetectors.begin(); for (; it != allDetectors.end(); ++it) { Geometry::IDetector_const_sptr det = it->second; if ((!det->isMasked()) && (!det->isMonitor())) { const detid_t detID = it->first; double offset = 0.; if (m_offsetsWS) offset = m_offsetsWS->getValue(detID, 0.); double difc = Geometry::Instrument::calcConversion( l1, beamline, beamline_norm, samplePos, det, offset); difc = 1. / difc; // calcConversion gives 1/DIFC localWS->setValue(detID, difc); } } }
/** * Make a map of the conversion factors between tof and D-spacing * for all pixel IDs in a workspace. * * @param DFileName name of dspacemap file * @param offsetsWS :: OffsetsWorkspace with instrument and offsets */ void SaveDspacemap::CalculateDspaceFromCal(Mantid::DataObjects::OffsetsWorkspace_sptr offsetsWS, std::string DFileName) { const char * filename = DFileName.c_str(); // Get a pointer to the instrument contained in the workspace Instrument_const_sptr instrument = offsetsWS->getInstrument(); double l1; Kernel::V3D beamline,samplePos; double beamline_norm; instrument->getInstrumentParameters(l1,beamline,beamline_norm, samplePos); //To get all the detector ID's detid2det_map allDetectors; instrument->getDetectors(allDetectors); detid2det_map::const_iterator it; detid_t maxdetID = 0; for (it = allDetectors.begin(); it != allDetectors.end(); it++) { detid_t detectorID = it->first; if(detectorID > maxdetID) maxdetID = detectorID; } detid_t paddetID = detid_t(getProperty("PadDetID")); if (maxdetID < paddetID)maxdetID = paddetID; // Now write the POWGEN-style Dspace mapping file std::ofstream fout(filename, std::ios_base::out|std::ios_base::binary); Progress prog(this,0.0,1.0,maxdetID); for (detid_t i = 0; i != maxdetID; i++) { //Compute the factor double factor; Geometry::IDetector_const_sptr det; // Find the detector with that detector id it = allDetectors.find(i); if (it != allDetectors.end()) { det = it->second; factor = Instrument::calcConversion(l1, beamline, beamline_norm, samplePos, det, offsetsWS->getValue(i, 0.0)); //Factor of 10 between ISAW and Mantid factor *= 0.1 ; if(factor<0)factor = 0.0; fout.write( reinterpret_cast<char*>( &factor ), sizeof(double) ); } else { factor = 0; fout.write( reinterpret_cast<char*>( &factor ), sizeof(double) ); } //Report progress prog.report(); } fout.close(); }
/** * Make a map of the conversion factors between tof and D-spacing * for all pixel IDs in a workspace. * * @param DFileName :: name of dspacemap file * @param offsetsWS :: OffsetsWorkspace to be filled. */ void LoadDspacemap::CalculateOffsetsFromDSpacemapFile( const std::string DFileName, Mantid::DataObjects::OffsetsWorkspace_sptr offsetsWS) { // Get a pointer to the instrument contained in the workspace Instrument_const_sptr instrument = offsetsWS->getInstrument(); double l1; Kernel::V3D beamline, samplePos; double beamline_norm; instrument->getInstrumentParameters(l1, beamline, beamline_norm, samplePos); // To get all the detector ID's detid2det_map allDetectors; instrument->getDetectors(allDetectors); // Read in the POWGEN-style Dspace mapping file const char *filename = DFileName.c_str(); std::ifstream fin(filename, std::ios_base::in | std::ios_base::binary); std::vector<double> dspace; double read; while (!fin.eof()) { fin.read(reinterpret_cast<char *>(&read), sizeof read); // Factor of 10 between ISAW and Mantid read *= 10.; dspace.push_back(read); } 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; // Compute the factor double offset = 0.0; double factor = Instrument::calcConversion(l1, beamline, beamline_norm, samplePos, det, offset); offset = dspace[detectorID] / factor - 1.0; // Save in the map try { offsetsWS->setValue(detectorID, offset); } catch (std::invalid_argument &) { } } }
/** 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++; } }
/** * Make a map of the conversion factors between tof and D-spacing * for all pixel IDs in a workspace. * map vulcan should contain the module/module and stack/stack offset * * @param vulcan :: map between detector ID and vulcan correction factor. * @param offsetsWS :: OffsetsWorkspace to be filled. */ void LoadDspacemap::CalculateOffsetsFromVulcanFactors( std::map<detid_t, double> &vulcan, Mantid::DataObjects::OffsetsWorkspace_sptr offsetsWS) { // Get a pointer to the instrument contained in the workspace // At this point, instrument VULCAN has been created? Instrument_const_sptr instrument = offsetsWS->getInstrument(); g_log.notice() << "Name of instrument = " << instrument->getName() << std::endl; g_log.notice() << "Input map (dict): size = " << vulcan.size() << std::endl; // To get all the detector ID's detid2det_map allDetectors; instrument->getDetectors(allDetectors); detid2det_map::const_iterator it; int numfinds = 0; g_log.notice() << "Input number of detectors = " << allDetectors.size() << std::endl; // Get detector information double l1, beamline_norm; Kernel::V3D beamline, samplePos; instrument->getInstrumentParameters(l1, beamline, beamline_norm, samplePos); /*** A survey of parent detector std::map<detid_t, bool> parents; for (it = allDetectors.begin(); it != allDetectors.end(); it++){ int32_t detid = it->first; // def boost::shared_ptr<const Mantid::Geometry::IDetector> IDetector_const_sptr; std::string parentname = it->second->getParent()->getComponentID()->getName(); g_log.notice() << "Name = " << parentname << std::endl; // parents.insert(parentid, true); } ***/ /*** Here some special configuration for VULCAN is hard-coded here! * Including (1) Super-Parent Information ***/ Kernel::V3D referencePos; detid_t anydetinrefmodule = 21 * 1250 + 5; std::map<detid_t, Geometry::IDetector_const_sptr>::iterator det_iter = allDetectors.find(anydetinrefmodule); if (det_iter == allDetectors.end()) { throw std::invalid_argument("Any Detector ID is Instrument's detector"); } referencePos = det_iter->second->getParent()->getPos(); double refl2 = referencePos.norm(); double halfcosTwoThetaRef = referencePos.scalar_prod(beamline) / (refl2 * beamline_norm); double sinThetaRef = sqrt(0.5 - halfcosTwoThetaRef); double difcRef = sinThetaRef * (l1 + refl2) / CONSTANT; // Loop over all detectors in instrument to find the offset for (it = allDetectors.begin(); it != allDetectors.end(); ++it) { int detectorID = it->first; Geometry::IDetector_const_sptr det = it->second; double offset = 0.0; // Find the vulcan factor; double vulcan_factor = 0.0; std::map<detid_t, double>::const_iterator vulcan_iter = vulcan.find(detectorID); if (vulcan_iter != vulcan.end()) { vulcan_factor = vulcan_iter->second; numfinds++; } // g_log.notice() << "Selected Detector with ID = " << detectorID << " ID2 // = " << id2 << std::endl; proved to be same double intermoduleoffset = 0; double interstackoffset = 0; detid_t intermoduleid = detid_t(detectorID / 1250) * 1250 + 1250 - 2; vulcan_iter = vulcan.find(intermoduleid); if (vulcan_iter == vulcan.end()) { g_log.error() << "Cannot find inter-module offset ID = " << intermoduleid << std::endl; } else { intermoduleoffset = vulcan_iter->second; } detid_t interstackid = detid_t(detectorID / 1250) * 1250 + 1250 - 1; vulcan_iter = vulcan.find(interstackid); if (vulcan_iter == vulcan.end()) { g_log.error() << "Cannot find inter-module offset ID = " << intermoduleid << std::endl; } else { interstackoffset = vulcan_iter->second; } /*** This is the previous way to correct upon DIFC[module center pixel] // The actual factor is 10^(-value_in_the_file) vulcan_factor = pow(10.0,-vulcan_factor); // At this point, tof_corrected = vulcan_factor * tof_input // So this is the offset offset = vulcan_factor - 1.0; ***/ /*** New approach to correct based on DIFC of each pixel * Equation: offset = DIFC^(pixel)/DIFC^(parent)*(1+vulcan_offset)-1 * offset should be close to 0 ***/ // 1. calculate DIFC Kernel::V3D detPos; detPos = det->getPos(); // Now detPos will be set with respect to samplePos detPos -= samplePos; double l2 = detPos.norm(); double halfcosTwoTheta = detPos.scalar_prod(beamline) / (l2 * beamline_norm); double sinTheta = sqrt(0.5 - halfcosTwoTheta); double difc_pixel = sinTheta * (l1 + l2) / CONSTANT; // Kernel::V3D parentPos = det->getParent()->getPos(); // parentPos -= samplePos; // double l2parent = parentPos.norm(); // double halfcosTwoThetaParent = parentPos.scalar_prod(beamline)/(l2 * // beamline_norm); // double sinThetaParent = sqrt(0.5 - halfcosTwoThetaParent); // double difc_parent = sinThetaParent*(l1+l2parent)/CONSTANT; /*** Offset Replicate Previous Result offset = difc_pixel/difc_parent*(pow(10.0, -vulcan_factor))-1.0; ***/ offset = difc_pixel / difcRef * (pow(10.0, -(vulcan_factor + intermoduleoffset + interstackoffset))) - 1.0; // Save in the map try { offsetsWS->setValue(detectorID, offset); if (intermoduleid != 27498 && intermoduleid != 28748 && intermoduleid != 29998 && intermoduleid != 33748 && intermoduleid != 34998 && intermoduleid != 36248) { g_log.error() << "Detector ID = " << detectorID << " Inter-Module ID = " << intermoduleid << std::endl; throw std::invalid_argument("Indexing error!"); } } catch (std::invalid_argument &) { g_log.notice() << "Misses Detector ID = " << detectorID << std::endl; } } // for g_log.notice() << "Number of matched detectors =" << numfinds << std::endl; }