/** * createOneDetectorInstrument, creates the most simple possible definition of an instrument in which we can extract a valid L1 and L2 distance for unit calculations. * * Beam direction is along X, * Up direction is Y * * @param sourcePos : V3D position * @param samplePos : V3D sample position * @param detectorPos : V3D detector position * @return Instrument generated. */ Geometry::Instrument_sptr createMinimalInstrument(const Mantid::Kernel::V3D& sourcePos, const Mantid::Kernel::V3D& samplePos, const Mantid::Kernel::V3D& detectorPos ) { Instrument_sptr instrument = boost::make_shared<Instrument>(); instrument->setReferenceFrame( boost::make_shared<ReferenceFrame>(Mantid::Geometry::Y /*up*/, Mantid::Geometry::X /*along*/, Left, "0,0,0")); // A source ObjComponent *source = new ObjComponent("source"); source->setPos(sourcePos); source->setShape(createSphere(0.01 /*1cm*/, V3D(0,0,0), "1")); instrument->add(source); instrument->markAsSource(source); // A sample ObjComponent *sample = new ObjComponent("some-surface-holder"); sample->setPos(samplePos); sample->setShape(createSphere(0.01 /*1cm*/, V3D(0,0,0), "1")); instrument->add(sample); instrument->markAsSamplePos(sample); // A detector Detector *det = new Detector("point-detector", 1 /*detector id*/, NULL); det->setPos(detectorPos); det->setShape(createSphere(0.01 /*1cm*/, V3D(0,0,0), "1")); instrument->add(det); instrument->markAsDetector(det); return instrument; }
Geometry::Instrument_sptr createVirtualInstrument(Kernel::V3D sourcePos, Kernel::V3D samplePos, const std::vector<Kernel::V3D> &vecdetpos, const std::vector<detid_t> &vecdetid) { Instrument_sptr instrument = boost::make_shared<Instrument>(); instrument->setReferenceFrame( boost::make_shared<ReferenceFrame>(Mantid::Geometry::Y /*up*/, Mantid::Geometry::Z /*along*/, Right, "0,0,0")); // A source ObjComponent *source = new ObjComponent("source"); source->setPos(sourcePos); source->setShape(createSphere(0.01 /*1cm*/, V3D(0,0,0), "1")); instrument->add(source); instrument->markAsSource(source); // A sample ObjComponent *sample = new ObjComponent("some-surface-holder"); sample->setPos(samplePos); sample->setShape(createSphere(0.01 /*1cm*/, V3D(0,0,0), "1")); instrument->add(sample); instrument->markAsSamplePos(sample); // A detector size_t numdets = vecdetpos.size(); for (size_t i = 0; i < numdets; ++i) { Detector *det = new Detector("point-detector", vecdetid[i] /*detector id*/, NULL); det->setPos(vecdetpos[i]); // FIXME - should be cubi... pixel det->setShape(createSphere(0.01 /*1cm*/, V3D(0,0,0), "1")); instrument->add(det); instrument->markAsDetector(det); } return instrument; }
void addFullInstrumentToWorkspace(MatrixWorkspace &workspace, bool includeMonitors, bool startYNegative, const std::string &instrumentName) { auto instrument = boost::make_shared<Instrument>(instrumentName); instrument->setReferenceFrame( boost::make_shared<ReferenceFrame>(Y, Z, Right, "")); workspace.setInstrument(instrument); const double pixelRadius(0.05); Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder( pixelRadius, 0.02, V3D(0.0, 0.0, 0.0), V3D(0., 1.0, 0.), "tube"); const double detZPos(5.0); // Careful! Do not use size_t or auto, the unisgned will break the -=2 below. int ndets = static_cast<int>(workspace.getNumberHistograms()); if (includeMonitors) ndets -= 2; for (int i = 0; i < ndets; ++i) { std::ostringstream lexer; lexer << "pixel-" << i << ")"; Detector *physicalPixel = new Detector(lexer.str(), workspace.getAxis(1)->spectraNo(i), pixelShape, instrument.get()); int ycount(i); if (startYNegative) ycount -= 1; const double ypos = ycount * 2.0 * pixelRadius; physicalPixel->setPos(0.0, ypos, detZPos); instrument->add(physicalPixel); instrument->markAsDetector(physicalPixel); workspace.getSpectrum(i).setDetectorID(physicalPixel->getID()); } // Monitors last if (includeMonitors) // These occupy the last 2 spectra { Detector *monitor1 = new Detector("mon1", workspace.getAxis(1)->spectraNo(ndets), Object_sptr(), instrument.get()); monitor1->setPos(0.0, 0.0, -9.0); instrument->add(monitor1); instrument->markAsMonitor(monitor1); workspace.getSpectrum(ndets).setDetectorID(ndets + 1); Detector *monitor2 = new Detector("mon2", workspace.getAxis(1)->spectraNo(ndets) + 1, Object_sptr(), instrument.get()); monitor2->setPos(0.0, 0.0, -2.0); instrument->add(monitor2); instrument->markAsMonitor(monitor2); workspace.getSpectrum(ndets + 1).setDetectorID(ndets + 2); } // Define a source and sample position // Define a source component ObjComponent *source = new ObjComponent( "moderator", ComponentCreationHelper::createSphere(0.1, V3D(0, 0, 0), "1"), instrument.get()); source->setPos(V3D(0.0, 0.0, -20.0)); instrument->add(source); instrument->markAsSource(source); // Define a sample as a simple sphere ObjComponent *sample = new ObjComponent( "samplePos", ComponentCreationHelper::createSphere(0.1, V3D(0, 0, 0), "1"), instrument.get()); instrument->setPos(0.0, 0.0, 0.0); instrument->add(sample); instrument->markAsSamplePos(sample); // chopper position Component *chop_pos = new Component("chopper-position", Kernel::V3D(0, 0, -10), instrument.get()); instrument->add(chop_pos); }
/** * Create an test instrument with n panels of rectangular detectors, *pixels*pixels in size, * a source and spherical sample shape. * * Banks' lower-left corner is at position (0,0,5*banknum) and they go up to *(pixels*0.008, pixels*0.008, Z) * Pixels are 4 mm wide. * * @param progress :: progress indicator * @param num_banks :: number of rectangular banks to create * @param pixels :: number of pixels in each direction. * @param pixelSpacing :: padding between pixels * @param bankDistanceFromSample :: Distance of first bank from sample (defaults *to 5.0m) * @param sourceSampleDistance :: The distance from the source to the sample * @returns A shared pointer to the generated instrument */ Instrument_sptr CreateSampleWorkspace::createTestInstrumentRectangular( API::Progress &progress, int num_banks, int pixels, double pixelSpacing, const double bankDistanceFromSample, const double sourceSampleDistance) { boost::shared_ptr<Instrument> testInst(new Instrument("basic_rect")); // The instrument is going to be set up with z as the beam axis and y as the // vertical axis. testInst->setReferenceFrame( boost::shared_ptr<ReferenceFrame>(new ReferenceFrame(Y, Z, Left, ""))); const double cylRadius(pixelSpacing / 2); const double cylHeight(0.0002); // One object Object_sptr pixelShape = createCappedCylinder( cylRadius, cylHeight, V3D(0.0, -cylHeight / 2.0, 0.0), V3D(0., 1.0, 0.), "pixel-shape"); for (int banknum = 1; banknum <= num_banks; banknum++) { // Make a new bank std::ostringstream bankname; bankname << "bank" << banknum; RectangularDetector *bank = new RectangularDetector(bankname.str()); bank->initialize(pixelShape, pixels, 0.0, pixelSpacing, pixels, 0.0, pixelSpacing, banknum * pixels * pixels, true, pixels); // Mark them all as detectors for (int x = 0; x < pixels; x++) for (int y = 0; y < pixels; y++) { boost::shared_ptr<Detector> detector = bank->getAtXY(x, y); if (detector) // Mark it as a detector (add to the instrument cache) testInst->markAsDetector(detector.get()); } testInst->add(bank); // Set the bank along the z-axis of the instrument. (beam direction). bank->setPos(V3D(0.0, 0.0, bankDistanceFromSample * banknum)); progress.report(); } // Define a source component ObjComponent *source = new ObjComponent("moderator", Object_sptr(new Object), testInst.get()); source->setPos(V3D(0.0, 0.0, -sourceSampleDistance)); testInst->add(source); testInst->markAsSource(source); // Add chopper ObjComponent *chopper = new ObjComponent( "chopper-position", Object_sptr(new Object), testInst.get()); chopper->setPos(V3D(0.0, 0.0, -0.25 * sourceSampleDistance)); testInst->add(chopper); // Define a sample as a simple sphere Object_sptr sampleSphere = createSphere(0.001, V3D(0.0, 0.0, 0.0), "sample-shape"); ObjComponent *sample = new ObjComponent("sample", sampleSphere, testInst.get()); testInst->setPos(0.0, 0.0, 0.0); testInst->add(sample); testInst->markAsSamplePos(sample); return testInst; }