void Mock1Test::testMock1() { debug(LOG_DEBUG, DEBUG_LOG, 0, "Mock1Test begin"); ModulePtr module = repository->getModule("mock1"); debug(LOG_DEBUG, DEBUG_LOG, 0, "got module"); module->open(); debug(LOG_DEBUG, DEBUG_LOG, 0, "module open"); DeviceLocatorPtr cl = module->getDeviceLocator(); debug(LOG_DEBUG, DEBUG_LOG, 0, "get DeviceLocator"); std::vector<std::string> cameras = cl->getDevicelist(); debug(LOG_DEBUG, DEBUG_LOG, 0, "get %d devices", cameras.size()); CPPUNIT_ASSERT(cameras.size() == 10); CameraPtr camera = cl->getCamera("camera:mock1/5"); // for every CCD, take an image for (unsigned int i = 0; i < camera->nCcds(); i++) { CcdPtr ccd = camera->getCcd(i); Exposure exposure; ImageRectangle frame(ImagePoint(1,1), ImageSize(ccd->getSize().width() - 2, ccd->getSize().height() - 2)); exposure.frame(frame); ccd->startExposure(exposure); while (ccd->exposureStatus() == Exposure::exposing) { sleep(1); } if (ccd->exposureStatus() == Exposure::exposed) { ImagePtr image = ccd->getImage(); debug(LOG_DEBUG, DEBUG_LOG, 0, "result image size: %d x %d", image->size().width(), image->size().height()); } } debug(LOG_DEBUG, DEBUG_LOG, 0, "Mock1Test end"); }
void SimGuiderPortTest::testRotation() { debug(LOG_DEBUG, DEBUG_LOG, 0, "start GuiderPort rotation test"); // get and configure the guider port SimGuiderPort *simguiderport = locator->simguiderport(); simguiderport->omega(0.01); // get camera and ccd and retrieve an image CameraPtr camera = locator->getCamera("camera:simulator/camera"); CcdPtr ccd = camera->getCcd(0); Exposure exposure; exposure.exposuretime(1); ccd->startExposure(exposure); ccd->wait(); ImagePtr image = ccd->getImage(); // advance the time and take another image simtime_advance(10); ccd->startExposure(exposure); ccd->wait(); image = ccd->getImage(); { FITSout out("guiderporttest-rotated.fits"); out.setPrecious(false); out.write(image); } debug(LOG_DEBUG, DEBUG_LOG, 0, "end GuiderPort rotation test"); }
/** * \brief Symmetrize the exposure * * The M26C has an interlaced CCD which reads the different fields and * colors from different sides of the chip. This only works for symmetric * exposures, symmetric with respect to the center of the CCD chip. This * method computes a symmetrized exposure object. */ Exposure SxCcdM26C::symmetrize(const Exposure& exp) const { debug(LOG_DEBUG, DEBUG_LOG, 0, "symmetrizing exposure %s", exp.toString().c_str()); Exposure symexp = exp; int x[4], y[4]; // compute all the possible corner coordinates x[0] = exp.x(); y[0] = exp.y(); x[1] = M26C_WIDTH - x[0]; y[1] = M26C_HEIGHT - y[0]; x[2] = exp.x() + exp.width(); y[2] = exp.y() + exp.height(); x[3] = M26C_WIDTH - x[2]; y[3] = M26C_HEIGHT - y[2]; debug(LOG_DEBUG, DEBUG_LOG, 0, "x[] = %d %d %d %d", x[0], x[1], x[2], x[3]); debug(LOG_DEBUG, DEBUG_LOG, 0, "y[] = %d %d %d %d", y[0], y[1], y[2], y[3]); // make the origin with the right divisibility int xmin = ((min(x, 4) >> 2) << 2) - 4; if (xmin < 0) { xmin = 0; } int xmax = M26C_WIDTH - xmin; int ymin = ((min(y, 4) >> 2) << 2) - 4; if (ymin < 0) { ymin = 0; } int ymax = M26C_HEIGHT - ymin; // symmetrized origin ImagePoint origin(xmin, ymin); // symmetrize size unsigned int sizex = xmax - xmin; if (sizex > 3900) { sizex = 3900; } unsigned int sizey = ymax - ymin; ImageSize size(sizex, sizey); ImageRectangle frame(origin, size); symexp.frame(frame); debug(LOG_DEBUG, DEBUG_LOG, 0, "symmetrized exposure: %s", symexp.toString().c_str()); return symexp; }
/** * \brief Start an exposure on the M26C camera * * \param exposure exposure structure for the exposure to perform */ void SxCcdM26C::startExposure0(const Exposure& exposure) { debug(LOG_DEBUG, DEBUG_LOG, 0, "exposure %s requested", exposure.toString().c_str()); // remember the exposre, we need it for the second field for the // case where we do two fields one after the other this->exposure = symmetrize(exposure); m26c = m26cExposure(); // compute a better request for the M26C camera exposeField(0); timer.start(); // we are now in exposing state state = Exposure::exposing; }
void QsiCcd::startExposure(const Exposure& exposure) { std::unique_lock<std::recursive_mutex> lock(_camera.mutex); Ccd::startExposure(exposure); debug(LOG_DEBUG, DEBUG_LOG, 0, "start QSI exposure"); try { // set the binning mode _camera.camera().put_BinX(exposure.mode().x()); _camera.camera().put_BinY(exposure.mode().y()); // compute the frame size in binned pixels, as this is what // the QSI camera expects ImagePoint origin = exposure.frame().origin() / exposure.mode(); ImageSize size = exposure.frame().size() / exposure.mode(); ImageRectangle frame(origin, size); debug(LOG_DEBUG, DEBUG_LOG, 0, "requesting %s image", frame.toString().c_str()); // set the subframe _camera.camera().put_NumX(size.width()); _camera.camera().put_NumY(size.height()); _camera.camera().put_StartX(origin.x()); _camera.camera().put_StartY(origin.y()); // turn off the led debug(LOG_DEBUG, DEBUG_LOG, 0, "turn LED off"); _camera.camera().put_LEDEnabled(false); // get shutter info bool light = (exposure.shutter() == Shutter::OPEN); _camera.camera().StartExposure(exposure.exposuretime(), light); debug(LOG_DEBUG, DEBUG_LOG, 0, "%fsec %s exposure started", exposure.exposuretime(), (light) ? "light" : "dark"); } catch (const std::exception& x) { debug(LOG_ERR, DEBUG_LOG, 0, "bad exposure parameters: %s", x.what()); cancelExposure(); throw BadParameter(x.what()); } // check the current state of the camera exposureStatus(); }
/** * \brief Start an exposure on the M26C camera * * \param exposure exposure structure for the exposure to perform */ void SxCcdM26C::startExposure0(const Exposure& exposure) { debug(LOG_DEBUG, DEBUG_LOG, 0, "exposure %s requested", exposure.toString().c_str()); // remember the exposure, we need it for the second field for the // case where we do two fields one after the other this->exposure = symmetrize(exposure); // compute a better request for the M26C camera m26c = m26cExposure(); // start the exposure if (!camera.reserve("exposure M26C", 1000)) { std::string msg("cannot reserve camera"); debug(LOG_ERR, DEBUG_LOG, 0, "%s", msg.c_str()); throw std::runtime_error(msg); } exposeField(0); timer.start(); // we are now in exposing state state(CcdState::exposing); }
int main(int argc, char *argv[]) { debugthreads = 1; Exposure exposure; unsigned int nImages = 1; std::string reponame; std::string filtername; int c; int longindex; double temperature = std::numeric_limits<double>::quiet_NaN(); while (EOF != (c = getopt_long(argc, argv, "b:c:de:f:hn:p:r:t:?", longopts, &longindex))) switch (c) { case 'b': exposure.mode(Binning(optarg)); break; case 'c': Configuration::set_default(optarg); break; case 'd': debuglevel = LOG_DEBUG; break; case 'e': exposure.exposuretime(atof(optarg)); break; case 'f': filtername = std::string(optarg); break; case 'h': case '?': usage(argv[0]); return EXIT_SUCCESS; case 'n': nImages = atoi(optarg); break; case 'p': exposure.purpose(Exposure::string2purpose(optarg)); break; case 'r': reponame = std::string(optarg); break; case 't': temperature = atof(optarg); break; case 1: exposure.frame(ImageRectangle(optarg)); break; default: throw std::runtime_error("unknown option"); } // next argument must be instrument name or help if (optind >= argc) { std::cerr << "missing instrument name" << std::endl; return EXIT_FAILURE; } std::string instrumentname(argv[optind++]); // get the configuration ConfigurationPtr config = Configuration::get(); // backend for instruments InstrumentBackend instrumentbackend(config->database()); InstrumentPtr instrument = instrumentbackend.get(instrumentname); // get the image repository ImageRepoPtr repo(NULL); if (reponame.size() > 0) { ImageRepoConfigurationPtr imagerepos = ImageRepoConfiguration::get(config); repo = imagerepos->repo(reponame); } // prepare a repository from which we can extract the devices Repository repository; Devices devices(repository); // get the devices CameraPtr camera = devices.getCamera(instrument->getCamera(0).deviceurl()); CcdPtr ccd = devices.getCcd(instrument->getCcd(0).deviceurl()); // If temperature is set, and a cooler is present, initialize the // cooler and wait until temperature is reached CoolerPtr cooler(NULL); if ((temperature == temperature) && (instrument->hasCooler())) { double absolute = 273.15 + temperature; if (absolute < 0) { std::string msg = stringprintf("illegal temperature: %f", temperature); debug(LOG_ERR, DEBUG_LOG, 0, "%s", msg.c_str()); throw std::runtime_error(msg); } cooler = devices.getCooler(instrument->getCooler(0).deviceurl()); cooler->setTemperature(absolute); cooler->setOn(true); double delta; do { double actual = cooler->getActualTemperature(); delta = fabs(absolute - actual); debug(LOG_DEBUG, DEBUG_LOG, 0, "set: %.1f, actual: %.1f, delta: %.1f", absolute, actual, delta); } while (delta > 1); } // if the instrument has a filter wheel, we get a pointer to it // and try FilterWheelPtr filterwheel(NULL); if (instrument->hasFilterWheel()) { filterwheel = devices.getFilterWheel( instrument->getFilterWheel(0).deviceurl()); filterwheel->wait(20); if (filtername.size() > 0) { filterwheel->select(filtername); filterwheel->wait(20); } } // start the stream unsigned int imagesRetrieved = 0; ccd->startStream(exposure); while (imagesRetrieved < nImages) { ImagePtr image = ccd->getEntry(true).image; debug(LOG_DEBUG, DEBUG_LOG, 0, "got image[%u] %s", ++imagesRetrieved, image->size().toString().c_str()); if (!image->hasMetadata(std::string("INSTRUME"))) { image->setMetadata(FITSKeywords::meta( std::string("INSTRUME"), instrument->name())); } // do something about the image if (repo) { repo->save(image); } } // stop the stream ccd->stopStream(); // find out how many images were dropped if (ccd->dropped() > 0) { std::cerr << "images dropped: " << ccd->dropped() << std::endl; } // turn off the cooler if (cooler) { cooler->setOn(false); } return EXIT_SUCCESS; }
/** * \brief Symmetrize the exposure * * The M26C has an interlaced CCD which reads the different fields and * colors from different sides of the chip. This only works for symmetric * exposures, symmetric with respect to the center of the CCD chip. This * method computes a symmetrized exposure object. */ Exposure SxCcdM26C::symmetrize(const Exposure& exp) const { debug(LOG_DEBUG, DEBUG_LOG, 0, "symmetrizing exposure %s", exp.toString().c_str()); Exposure symexp = exp; int x[4], y[4]; x[0] = exp.x(); y[0] = exp.y(); x[1] = M26C_WIDTH - x[0]; y[1] = M26C_HEIGHT - y[0]; x[2] = exp.x() + exp.width(); y[2] = exp.y() + exp.height(); x[3] = M26C_WIDTH - x[2]; y[3] = M26C_HEIGHT - y[2]; debug(LOG_DEBUG, DEBUG_LOG, 0, "x[] = %d %d %d %d", x[0], x[1], x[2], x[3]); debug(LOG_DEBUG, DEBUG_LOG, 0, "y[] = %d %d %d %d", y[0], y[1], y[2], y[3]); // symmetrized origin ImagePoint origin(min(x, 4), min(y, 4)); // symmetrize size unsigned int sizex = max(x, 4) - symexp.x(); if (sizex > 3900) { sizex = 3900; } unsigned int sizey = max(y, 4) - symexp.y(); ImageSize size(sizex, sizey); ImageRectangle frame(origin, size); symexp.frame(frame); debug(LOG_DEBUG, DEBUG_LOG, 0, "symmetrized exposure: %s", symexp.toString().c_str()); return symexp; }