// HbookDataset.cxx #include "dataset_CBNT/HbookDataset.h" #include #include #include #include #include "dataset_util/Path.h" #include "dataset_util/ssystem.h" #include "dataset_util/copy_file.h" #include "dataset_util/XmlElement.h" #include "dataset_util/DtdRegistry.h" #include "dataset_util/FileStatus.h" #include "dataset_file/FileManagementSystem.h" #include "dataset_base/DatasetCreator.h" #include "dataset_CBNT/HbookFile.h" using std::string; using std::vector; using std::ostream; using std::ostringstream; using std::cout; using std::endl; using std::setw; using std::setfill; using dset::Url; using dset::FileManagementSystem; using dset::Location; using dset::Dataset; using dset::DatasetCreator; using dset::GenericDataset; using dset::HbookDataset; //********************************************************************** // Local data. //********************************************************************** namespace { // For debugging. int verbose = 0; // HBOOK directory names. string NTDIR = " "; string PWDIR = " "; // Generate a new file name. string make_file_name(string dir) { if ( dir.size() == 0 ) return ""; if ( ! FileStatus(dir).is_directory() ) return ""; if ( ! FileStatus(dir).is_writeable() ) return ""; for ( int i=0; i<100000; ++i ) { ostringstream sname; sname << dir << "/" << "dataset" << setw(6) << setfill('0') << i << ".hbk"; string name = sname.str(); if ( ! FileStatus(name).exists() ) { return name; } } return ""; } } // end unnamed namespace //********************************************************************** // FORTRAN declarations. //********************************************************************** extern "C" { // Initialize HBOOK (and zebra and paw). int pawin_(); // Directory listing. void hldir_(const char* path, const char* opt, int lpath, int lopt); // Change directory. void hcdir_(const char* path, const char* opt, int lpath, int lopt); // Read into memory. void hrin_(int* id, int* cycle, int* offset); // hexist bool hexist_(int* id); // Print ntuple properties. void hprnt_(int* id); // Fetch ntuple blocks //void hbloks_(int* id); void hbloks_(const int* id, const int* maxnam, int* nnam, char bnames[][8]); // Description of the variables in a row. void hbname_(int* id, const char* bname, int* address, char* form); void evids_(int* id, int* nevt, int* runs, int* evts); } // end extern "C" //********************************************************************** // Helper functions. //********************************************************************** namespace { //********************************************************************** // HBOOK directory listing. void hldir(string path, string opt) { hldir_(path.c_str(), opt.c_str(), path.size(), opt.size()); } //********************************************************************** // HBOOK directory change. void hcdir(string path, string opt ="") { hcdir_(path.c_str(), opt.c_str(), path.size(), opt.size()); } //********************************************************************** // Register promoter int HbookDataset_xml_stat = GenericDataset:: register_promoter("HbookDataset", dset::promote); //********************************************************************** } // end unnamed namespace //********************************************************************** // Member functions. //********************************************************************** // Constructor from file. HbookDataset::HbookDataset(Url file, bool lockit) : m_file(file), m_phfile(0) { // Require valid logical file. if ( ! m_file.is_valid() ) { set_error(11); return; } // Set full type. set_fulltype("HbookDataset"); // Set ID's. set_id(); // Set the location. Location loc; loc.files().push_back(file); if ( set_location(loc) != 0 ) { set_error(12); return; } assert( location().files().size() == 1 ); // Set the content. if ( set_content_absent() != 0 ) { set_error(13); return; } set_evstate_none(); // Set lock status. if ( lockit ) lock(); } //********************************************************************** // Constructor from file and parent ID. HbookDataset:: HbookDataset(Url file, DatasetId pid, bool lockit) : m_file(file), m_phfile(0) { // Require valid logical file. if ( ! m_file.is_valid() ) { set_error(21); return; } // Set full type. set_fulltype("HbookDataset"); // Set ID's. set_id(); set_parent_id(pid); // Set the location. Location loc; loc.files().push_back(file); if ( set_location(loc) != 0 ) { set_error(22); return; } loc.files().push_back(file); assert( location().files().size() == 1 ); // Set the content. if ( set_content_absent() != 0 ) { set_error(23); return; } set_evstate_none(); // Set lock status. if ( lockit ) lock(); } //********************************************************************** // Generic dataset constructor. HbookDataset::HbookDataset(const GenericDataset& gdst) : GenericDataset(gdst), m_phfile(0) { // OK if input dataset is of the same type. if ( fulltype() == "HbookDataset" ) { assert( content_storage_state() == ABSENT ); assert( location_storage_state() == EXPLICIT ); assert( location().files().size() == 1 ); return; } // If input is SingleFileDataset, extract the file. if ( fulltype() == "SingleFileDataset" ) { if ( location().files().size() != 1 ) { set_error(41); return; } if ( content_storage_state() != IMPLICIT ) { set_error(42); return; } int stat = unset_content(); stat += set_content_absent(); return; } set_error(50); return; } //********************************************************************** // Copy constructor. HbookDataset::HbookDataset(const HbookDataset& rhs) : GenericDataset(rhs), m_phfile(0) { } //********************************************************************** // Destructor. HbookDataset::~HbookDataset() { delete m_phfile; } //********************************************************************** // Logical file. Url HbookDataset::file() const { if ( ! m_file.is_valid() ) { assert( location().files().size() == 1 ); m_file = location().files().front(); } return m_file; } //********************************************************************** // Filename. string HbookDataset::filename() const { assert( location().files().size() == 1 ); return file().fullpath(); } //********************************************************************** // HBOOK file. HbookFile& HbookDataset::hbook_file() const { static HbookFile bad_hfile; if ( ! is_valid() ) return bad_hfile; if ( m_phfile == 0 ) { HbookFile* phbfile = new HbookFile(filename()); if ( ! is_valid() ) { delete phbfile; return bad_hfile; } m_phfile = phbfile; } return *m_phfile; } //********************************************************************** // Lock. int HbookDataset::lock() { int stat = GenericDataset::lock(); if ( stat != 0 ) return stat; return 0; } //********************************************************************** // Clone. HbookDataset* HbookDataset::clone(string dir) const { if ( ! is_locked() ) return 0; FileManagementSystem& fms = FileManagementSystem::default_instance(); Url durl("file:" + dir); Url newurl = fms.copy(m_file, durl); if ( ! m_file.size() ) { return 0; } // Create dataset. return new HbookDataset(newurl, id(), false); } //********************************************************************** // Merge. int HbookDataset::merge(const Dataset& dst, string) { // Cast argument. if ( ! dst.is() ) return 1; const HbookDataset& hdst = dst.cast(); // Check lock status. if ( is_locked() ) { return 2; } // Check argument lock status. if ( ! dst.is_locked() ) { return 3; } char chardir[32] = "/tmp/mergeXXXXXX"; mkdtemp(chardir); string mergedir = chardir; // Check input directory. if ( ! FileStatus(mergedir).is_directory() ) { return 6; } // Find paw. Path exepath; exepath.getenv("PATH"); if ( exepath.size() == 0 ) return 8; Path pawpath = exepath.find("paw"); if ( pawpath.size() == 0 ) return 9; string pawexe = pawpath.front() + "/paw"; if ( ! FileStatus(pawexe).is_executable() ) return 10; // Extract filenames. Url file1 = file(); string hfile1 = file1.fullpath(); if ( hfile1.size() == 0 ) return 11; if ( ssystem("ln -sf " + hfile1 + " " + mergedir +"/file1") != 0 ) return 12; Url file2 = hdst.file(); string hfile2 = file2.fullpath(); if ( hfile2.size() == 0 ) return 13; if ( ssystem("ln -sf " + hfile2 + " " + mergedir +"/file2") != 0 ) return 14; // Build kumac. Text kum(mergedir + "/merge.kumac"); kum.append("histo/file 1 file1 chopt=u"); kum.append("hrin *"); kum.append("histo/file 2 file2"); kum.append("hrin * ! 99999"); kum.append("close 2"); kum.append("cd //LUN1"); kum.append("hrout *"); kum.append("close 1"); kum.write(); // Run paw. int stat = ssystem("cd " + mergedir + "; " + pawexe + " -b " + kum.name() + " > /dev/null 2>&1"); if ( stat != 0 ) return 15; // Remove directory. if ( ssystem("rm -rf " + mergedir) != 0 ) return 7; return 0; } //**********************************************************************