diff --git a/camerad/archon.cpp b/camerad/archon.cpp index 0a691ad6..d0825ad7 100644 --- a/camerad/archon.cpp +++ b/camerad/archon.cpp @@ -88,6 +88,8 @@ namespace Archon { this->frame.buftimestamp.resize( Archon::nbufs ); this->frame.bufretimestamp.resize( Archon::nbufs ); this->frame.buffetimestamp.resize( Archon::nbufs ); + + image_output_type = "disk"; } // Archon::Interface deconstructor @@ -95,6 +97,14 @@ namespace Archon { Interface::~Interface() = default; + ImageOutput* Interface::get_image_output() { + if (!image_output) { + output_handler = ImageOutputFactory::create_image_output(image_output_type); + image_output = dynamic_cast(output_handler.get()); + } + return image_output; + } + /**************** Archon::Interface::interface ******************************/ long Interface::interface(std::string &iface) { std::string function = "Archon::Interface::interface"; @@ -1340,7 +1350,7 @@ namespace Archon { * */ long Interface::load_acf(std::string acffile) { - std::string function = "Archon::Interface::load_acf"; + const std::string function("Archon::Interface::load_acf"); std::stringstream message; std::fstream filestream; // I/O stream class std::string line; // the line read from the acffile @@ -1750,11 +1760,13 @@ namespace Archon { logwrite(function, "loaded Archon config file OK"); this->firmwareloaded = true; - // add to systemkeys keyword database + // add firmware filename and checksum to systemkeys keyword database // - std::stringstream keystr; - keystr << "FIRMWARE=" << acffile << "// controller firmware"; - this->systemkeys.addkey( keystr.str() ); + this->systemkeys.addkey( "FIRMWARE=" + acffile + "// controller firmware" ); + + std::string hash; + md5_file( acffile, hash ); + this->systemkeys.addkey( "FIRM_MD5=" + hash + "// MD5 checksum of firmware" ); } // If there was an Archon error then read the Archon error log @@ -3300,7 +3312,7 @@ namespace Archon { logwrite( function, message.str() ); #endif - error = this->fits_file.write_image(fext, this->camera_info); // write the image to disk + error = this->get_image_output()->write_image(fext, this->camera_info); this->camera_info.extension++; // increment extension for cubes if ( fext != nullptr ) { delete [] fext; fext=nullptr; } // dynamic object not automatic so must be destroyed @@ -3326,7 +3338,7 @@ namespace Archon { } // error = fits_file.write_image(fbuf, this->fits_info); // write the image to disk //TODO - error = this->fits_file.write_image(fbuf, this->camera_info); // write the image to disk + error = this->get_image_output()->write_image(fbuf, this->camera_info); if ( error != NO_ERROR ) { this->camera.log_error( function, "writing 32-bit image to disk" ); } delete [] fbuf; } @@ -3339,7 +3351,7 @@ namespace Archon { if (this->camera_info.datatype == USHORT_IMG) { // raw cbuf16 = (uint16_t *)this->image_data; // cast to 16b unsigned int // error = fits_file.write_image(cbuf16, this->fits_info); // write the image to disk //TODO - error = this->fits_file.write_image(cbuf16, this->camera_info); // write the image to disk + error = this->get_image_output()->write_image(cbuf16, this->camera_info); if ( error != NO_ERROR ) { this->camera.log_error( function, "writing 16-bit raw image to disk" ); } } else if (this->camera_info.datatype == SHORT_IMG) { @@ -3349,7 +3361,7 @@ namespace Archon { for (long pix=0; pix < this->camera_info.section_size; pix++) { ibuf[pix] = cbuf16s[pix] - 32768; // subtract 2^15 from every pixel } - error = this->fits_file.write_image(ibuf, this->camera_info); // write the image to disk + error = this->get_image_output()->write_image(ibuf, this->camera_info); if ( error != NO_ERROR ) { this->camera.log_error( function, "writing 16-bit image to disk" ); } delete [] ibuf; @@ -3925,7 +3937,7 @@ namespace Archon { #ifdef LOGLEVEL_DEBUG logwrite( function, "[DEBUG] opening fits file for multi-exposure sequence data cube" ); #endif - error = this->fits_file.open_file(this->camera.writekeys_when == "before", this->camera_info ); + error = this->get_image_output()->open(this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); return error; @@ -4006,8 +4018,7 @@ namespace Archon { // reset the extension number and open the fits file // this->camera_info.extension = 0; - error = this->fits_file.open_file( - this->camera.writekeys_when == "before", this->camera_info ); + error = this->get_image_output()->open(this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); return error; @@ -4028,14 +4039,14 @@ namespace Archon { if ( error != NO_ERROR ) { logwrite( function, "ERROR: waiting for readout" ); - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); return error; } error = read_frame(); // then read the frame buffer to host (and write file) when frame ready. if ( error != NO_ERROR ) { logwrite( function, "ERROR: reading frame buffer" ); - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); return error; } @@ -4045,7 +4056,7 @@ namespace Archon { #ifdef LOGLEVEL_DEBUG logwrite( function, "[DEBUG] closing fits file (1)" ); #endif - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); // close the file when not using datacubes + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" // ASYNC status message on completion of each file @@ -4076,13 +4087,13 @@ namespace Archon { this->copy_keydb(); // copy the ACF and userkeys databases into camera_info - error = this->fits_file.open_file(this->camera.writekeys_when == "before", this->camera_info ); + error = this->get_image_output()->open(this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); return error; } error = read_frame(); // For raw mode just read immediately - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->open(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" } @@ -4092,7 +4103,7 @@ namespace Archon { #ifdef LOGLEVEL_DEBUG logwrite( function, "[DEBUG] closing fits file (2)" ); #endif - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" // ASYNC status message on completion of each file @@ -4917,7 +4928,7 @@ namespace Archon { #ifdef LOGLEVEL_DEBUG logwrite( function, "[DEBUG] opening fits file for multi-exposure sequence data cube" ); #endif - error = this->fits_file.open_file( + error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); @@ -4999,7 +5010,7 @@ namespace Archon { // reset the extension number and open the fits file // this->camera_info.extension = 0; - error = this->fits_file.open_file( + error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); @@ -5021,7 +5032,7 @@ namespace Archon { if ( error != NO_ERROR ) { logwrite( function, "ERROR: waiting for readout" ); - this->fits_file.close_file( + this->get_image_output()->close( this->camera.writekeys_when == "after", this->camera_info ); return error; } @@ -5029,7 +5040,7 @@ namespace Archon { error = read_frame(); // then read the frame buffer to host (and write file) when frame ready. if ( error != NO_ERROR ) { logwrite( function, "ERROR: reading frame buffer" ); - this->fits_file.close_file( + this->get_image_output()->close( this->camera.writekeys_when == "after", this->camera_info ); return error; } @@ -5040,7 +5051,7 @@ namespace Archon { #ifdef LOGLEVEL_DEBUG logwrite( function, "[DEBUG] closing fits file (1)" ); #endif - this->fits_file.close_file( + this->get_image_output()->close( this->camera.writekeys_when == "after", this->camera_info ); // close the file when not using datacubes this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" @@ -5072,14 +5083,14 @@ namespace Archon { this->copy_keydb(); // copy the ACF and userkeys databases into camera_info - error = this->fits_file.open_file( + error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); return error; } error = read_frame(); // For raw mode just read immediately - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" } @@ -5089,7 +5100,7 @@ namespace Archon { #ifdef LOGLEVEL_DEBUG logwrite( function, "[DEBUG] closing fits file (2)" ); #endif - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" // ASYNC status message on completion of each file @@ -6044,7 +6055,7 @@ namespace Archon { this->add_filename_key(); // add filename to system keys database this->camera_info.systemkeys.keydb = this->systemkeys.keydb; // copy the systemkeys database into camera_info if (this->camera.writekeys_when=="before") this->copy_keydb(); // copy the ACF and userkeys database into camera_info - error = this->fits_file.open_file(this->camera.writekeys_when == "before", this->camera_info ); + error = this->get_image_output()->open(this->camera.writekeys_when == "before", this->camera_info ); logwrite( function, "untimed exposure trigger enabled" ); return error; } @@ -6052,8 +6063,8 @@ namespace Archon { // For "disable" there's nothing more to do right now (except close any open FITS file) // if ( error == NO_ERROR && this->trigin_state == "disable" ) { - if ( this->fits_file.isopen() ) { // "untimed" could have opened a FITS file - this->fits_file.close_file( false, this->camera_info ); // close the FITS file container + if ( this->get_image_output()->is_open() ) { // "untimed" could have opened a FITS file + this->get_image_output()->close( false, this->camera_info ); // close the FITS file container std::remove( this->camera_info.fits_name.c_str() ); // remove the (empty) file it created } logwrite( function, "untimed exposure trigger disabled" ); @@ -6094,7 +6105,7 @@ namespace Archon { if (error==NO_ERROR) error = this->wait_for_readout(); // Wait for the readout into frame buffer, if (error==NO_ERROR) error = read_frame(); // then read the frame buffer to host (and write file) when frame ready. - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); // close the file when not using datacubes + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); // close the file when not using datacubes this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" // ASYNC status message on completion of each file @@ -6145,7 +6156,7 @@ namespace Archon { // Open the FITS file now for cubes // if ( this->camera.datacube() ) { - error = this->fits_file.open_file( + error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); @@ -6177,7 +6188,7 @@ namespace Archon { return error; } this->add_filename_key(); // add filename to system keys database - error = this->fits_file.open_file( + error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); @@ -6193,7 +6204,7 @@ namespace Archon { if (error==NO_ERROR) error = read_frame(); // then read the frame buffer to host (and write file) when frame ready. if ( !this->camera.datacube() ) { // Error or not, close the file. - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); // close the file when not using datacubes + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); // close the file when not using datacubes this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" // ASYNC status message on completion of each file @@ -6210,16 +6221,16 @@ namespace Archon { error = this->get_frame_status(); // Get the current frame buffer status if (error==NO_ERROR) error = this->camera.get_fitsname( this->camera_info.fits_name ); // Assemble the FITS filename this->add_filename_key(); // add filename to system keys database - if (error==NO_ERROR) error = this->fits_file.open_file( + if (error==NO_ERROR) error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if (error==NO_ERROR) error = read_frame(); // For raw mode just read immediately - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" } // for cubes, close the FITS file now that they've all been written // if ( this->camera.datacube() ) { - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" // ASYNC status message on completion of each file @@ -8006,7 +8017,7 @@ namespace Archon { // open the file now for datacubes // if ( this->camera.datacube() ) { - error = this->fits_file.open_file( + error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); @@ -8042,7 +8053,7 @@ namespace Archon { } this->add_filename_key(); // add filename to system keys database - error = this->fits_file.open_file( + error = this->get_image_output()->open( this->camera.writekeys_when == "before", this->camera_info ); if ( error != NO_ERROR ) { this->camera.log_error( function, "couldn't open fits file" ); @@ -8065,7 +8076,7 @@ namespace Archon { if (error==NO_ERROR && ro) error = this->read_frame(Camera::FRAME_IMAGE); // read image frame directly with no write if (error==NO_ERROR && rw) error = this->read_frame(); // read image frame directly with no write if (error==NO_ERROR && rw && !this->camera.datacube()) { - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" } if (error==NO_ERROR) frames_read++; @@ -8076,7 +8087,7 @@ namespace Archon { // (or any time there is an error) // if ( rw && ( this->camera.datacube() || (error==ERROR) ) ) { - this->fits_file.close_file(this->camera.writekeys_when == "after", this->camera_info ); + this->get_image_output()->close(this->camera.writekeys_when == "after", this->camera_info ); this->camera.increment_imnum(); // increment image_num when fitsnaming == "number" } diff --git a/utils/utilities.cpp b/utils/utilities.cpp index a4311ef5..b732fbf2 100644 --- a/utils/utilities.cpp +++ b/utils/utilities.cpp @@ -747,13 +747,9 @@ long md5_file(const std::string &filename, std::string &hash) { } instream.close(); - } catch (std::ifstream::failure &e) { - std::cerr << "md5_file( " << filename << " ): " << e.what() << "\n"; - hash = "ERROR"; - return 1; } catch (std::exception &e) { - std::cerr << "md5_file( " << filename << " ): " << e.what() << "\n"; + std::cerr << "ERROR md5_file( " << filename << " ): " << e.what() << "\n"; hash = "ERROR"; return 1; } @@ -772,7 +768,6 @@ long md5_file(const std::string &filename, std::string &hash) { return 0; } - /***** md5_file *************************************************************/