/** * Write bin masking information * @param ws :: The workspace * @return true for OK, false for error */ bool NexusFileIO::writeNexusBinMasking(API::MatrixWorkspace_const_sptr ws) const { std::vector< int > spectra; std::vector< std::size_t > bins; std::vector< double > weights; int spectra_count = 0; int offset = 0; for(std::size_t i=0;i<ws->getNumberHistograms(); ++i) { if (ws->hasMaskedBins(i)) { const API::MatrixWorkspace::MaskList& mList = ws->maskedBins(i); spectra.push_back(spectra_count); spectra.push_back(offset); API::MatrixWorkspace::MaskList::const_iterator it = mList.begin(); for(;it != mList.end(); ++it) { bins.push_back(it->first); weights.push_back(it->second); } ++spectra_count; offset += static_cast<int>(mList.size()); } } if (spectra_count == 0) return false; NXstatus status; // save spectra offsets as a 2d array of ints int dimensions[2]; dimensions[0]=spectra_count; dimensions[1]=2; status=NXmakedata(fileID, "masked_spectra", NX_INT32, 2, dimensions); if(status==NX_ERROR) return false; NXopendata(fileID, "masked_spectra"); const std::string description = "spectra index,offset in masked_bins and mask_weights"; NXputattr(fileID, "description", reinterpret_cast<void*>(const_cast<char*>(description.c_str())), static_cast<int>(description.size()+1), NX_CHAR); NXputdata(fileID, (void*)&spectra[0]); NXclosedata(fileID); // save masked bin indices dimensions[0]=static_cast<int>(bins.size()); status=NXmakedata(fileID, "masked_bins", NX_INT32, 1, dimensions); if(status==NX_ERROR) return false; NXopendata(fileID, "masked_bins"); NXputdata(fileID, (void*)&bins[0]); NXclosedata(fileID); // save masked bin weights dimensions[0]=static_cast<int>(bins.size()); status=NXmakedata(fileID, "mask_weights", NX_FLOAT64, 1, dimensions); if(status==NX_ERROR) return false; NXopendata(fileID, "mask_weights"); NXputdata(fileID, (void*)&weights[0]); NXclosedata(fileID); return true; }
/*----------------------------------------------------------------------*/ int nx_putds(void *handle, char *name, void *dataset){ NXhandle hfil; int status; pNXDS data; hfil = (NXhandle)handle; data = (pNXDS)dataset; status = NXopendata(hfil,name); if(status != NX_OK){ status = NXmakedata64(hfil,name,data->type,data->rank,data->dim); if(status != NX_OK){ return 0; } NXopendata(hfil,name); } status = NXputdata(hfil,data->u.ptr); NXclosedata(hfil); if(status != NX_OK){ return 0; }else{ return 1; } }
int NDFileNexus::processStreamData(NDArray *pArray) { int fileWriteMode; int numCapture; int slabOffset[ND_ARRAY_MAX_DIMS]; int slabSize[ND_ARRAY_MAX_DIMS]; int rank; int ii; int addr = 0; //static const char *functionName = "processNode"; /* Must lock when accessing parameter library */ this->lock(); getIntegerParam(addr, NDFileWriteMode, &fileWriteMode); getIntegerParam(addr, NDFileNumCapture, &numCapture); this->unlock(); rank = pArray->ndims; for (ii=0; ii<rank; ii++) { switch(fileWriteMode) { case NDFileModeSingle: slabOffset[(rank-1) - ii] = 0; slabSize[(rank-1) -ii] = (int)pArray->dims[ii].size; break; case NDFileModeCapture: case NDFileModeStream: slabOffset[(rank) - ii] = 0; slabSize[(rank) -ii] = (int)pArray->dims[ii].size; break; } } //printf ("%s: dataPath %s\ndataName %s\nimageNumber %d\n", functionName, this->dataPath, this->dataName, this->imageNumber); if (this->imageNumber == 0) { NXopenpath( this->nxFileHandle, this->dataPath); NXopendata( this->nxFileHandle, this->dataName); } switch (fileWriteMode) { case NDFileModeSingle: NXputdata(this->nxFileHandle, pArray->pData); break; case NDFileModeCapture: case NDFileModeStream: rank = rank+1; slabOffset[0] = this->imageNumber; slabSize[0] = 1; NXputslab(this->nxFileHandle, pArray->pData, slabOffset, slabSize); break; } if (this-> imageNumber == (numCapture-1) ) { NXclosedata(this->nxFileHandle); NXclosegroup(this->nxFileHandle ); } this->imageNumber++; return 0; }
/** * Save float data ald leave the dataset open. * @param name Name of the data set * @param data Pointer to the data source * @param size size of the data in sizeof(float) */ void SaveISISNexus::saveFloatOpen(const char *name, void *data, int size) { int dim[1]; dim[0] = size; // If we aren't going to anything with the status, then don't bother asking // for it! (NXstatus status = NXblah()) NXmakedata(handle, name, NX_FLOAT32, 1, dim); NXopendata(handle, name); NXputdata(handle, data); }
/** Write out an array to the open file. */ void NexusFileIO::NXwritedata( const char * name, int datatype, int rank, int * dims_array, void * data, bool compress) const { if (compress) { // We'll use the same slab/buffer size as the size of the array NXcompmakedata(fileID, name, datatype, rank, dims_array, m_nexuscompression, dims_array); } else { // Write uncompressed. NXmakedata(fileID, name, datatype, rank, dims_array); } NXopendata(fileID, name); NXputdata(fileID, data ); NXclosedata(fileID); }
/*----------------------------------------------------------------------*/ int nx_putdata(void *handle, void *dataset){ NXhandle hfil; int status; pNXDS data; hfil = (NXhandle)handle; data = (pNXDS)dataset; if(data == NULL){ NXReportError("ERROR: NULL data pointer in nx_putdata"); return 0; } status = NXputdata(hfil,data->u.ptr); if(status != NX_OK){ return 0; }else{ return 1; } }
/** Write out a combined chunk of event data * * @param ws :: an EventWorkspace * @param indices :: array of event list indexes * @param tofs :: array of TOFs * @param weights :: array of event weights * @param errorSquareds :: array of event squared errors * @param pulsetimes :: array of pulsetimes * @param compress :: if true, compress the entry */ int NexusFileIO::writeNexusProcessedDataEventCombined( const DataObjects::EventWorkspace_const_sptr& ws, std::vector<int64_t> & indices, double * tofs, float * weights, float * errorSquareds, int64_t * pulsetimes, bool compress) const { NXopengroup(fileID,"event_workspace","NXdata"); // The array of indices for each event list # int dims_array[1] = { static_cast<int>(indices.size()) }; if (indices.size() > 0) { if (compress) NXcompmakedata(fileID, "indices", NX_INT64, 1, dims_array, m_nexuscompression, dims_array); else NXmakedata(fileID, "indices", NX_INT64, 1, dims_array); NXopendata(fileID, "indices"); NXputdata(fileID, (void*)(indices.data()) ); std::string yUnits=ws->YUnit(); std::string yUnitLabel=ws->YUnitLabel(); NXputattr (fileID, "units", reinterpret_cast<void*>(const_cast<char*>(yUnits.c_str())), static_cast<int>(yUnits.size()), NX_CHAR); NXputattr (fileID, "unit_label", reinterpret_cast<void*>(const_cast<char*>(yUnitLabel.c_str())), static_cast<int>(yUnitLabel.size()), NX_CHAR); NXclosedata(fileID); } // Write out each field dims_array[0] = static_cast<int>(indices.back()); // TODO big truncation error! This is the # of events if (tofs) NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *)(tofs), compress); if (pulsetimes) NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *)(pulsetimes), compress); if (weights) NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *)(weights), compress); if (errorSquareds) NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *)(errorSquareds), compress); // Close up the overall group NXstatus status=NXclosegroup(fileID); return((status==NX_ERROR)?3:0); }
//----------------------------------------------------------------------------------------------- // // write an NXdata entry with String array values // bool NexusFileIO::writeNxStringArray(const std::string& name, const std::vector<std::string>& values, const std::vector<std::string>& attributes, const std::vector<std::string>& avalues) const { int dimensions[2]; size_t maxlen=0; dimensions[0]=static_cast<int>(values.size()); for(size_t i=0;i<values.size();i++) if(values[i].size()>maxlen) maxlen=values[i].size(); dimensions[1]=static_cast<int>(maxlen); NXstatus status=NXmakedata(fileID, name.c_str(), NX_CHAR, 2, dimensions); if(status==NX_ERROR) return(false); NXopendata(fileID, name.c_str()); for(size_t it=0; it<attributes.size(); ++it) NXputattr(fileID, attributes[it].c_str(), reinterpret_cast<void*>(const_cast<char*>(avalues[it].c_str())), static_cast<int>(avalues[it].size()+1), NX_CHAR); char* strs=new char[values.size()*maxlen]; for(size_t i=0;i<values.size();i++) { strncpy(&strs[i*maxlen],values[i].c_str(),maxlen); } NXputdata(fileID, (void*)strs); NXclosedata(fileID); delete[] strs; return(true); }
int main (int argc, char *argv[]) { int i, j, k, n, NXrank, NXdims[32], NXtype, NXlen, entry_status, attr_status; float r; void *data_buffer; unsigned char i1_array[4] = {1, 2, 3, 4}; short int i2_array[4] = {1000, 2000, 3000, 4000}; int i4_array[4] = {1000000, 2000000, 3000000, 4000000}; float r4_array[5][4] = {{1., 2., 3., 4.}, {5., 6., 7., 8.}, {9., 10., 11., 12.}, {13., 14., 15., 16.}, {17., 18., 19., 20.}}; double r8_array[5][4] = {{1., 2., 3., 4.}, {5., 6., 7., 8.}, {9., 10., 11., 12.}, {13., 14., 15., 16.}, {17., 18., 19., 20.}}; int array_dims[2] = {5, 4}; int unlimited_dims[1] = {NX_UNLIMITED}; int chunk_size[2]={5,4}; int slab_start[2], slab_size[2]; char name[64], char_class[64], char_buffer[128]; char group_name[64], class_name[64]; char c1_array[5][4] = {{'a', 'b', 'c' ,'d'}, {'e', 'f', 'g' ,'h'}, {'i', 'j', 'k', 'l'}, {'m', 'n', 'o', 'p'}, {'q', 'r', 's' , 't'}}; int unlimited_cdims[2] = {NX_UNLIMITED, 4}; NXhandle fileid, clone_fileid; NXlink glink, dlink, blink; int comp_array[100][20]; int dims[2]; int cdims[2]; int nx_creation_code; char nxFile[80]; char filename[256]; int64_t grossezahl[4]; const char* ch_test_data = "NeXus ><}&{'\\&\" Data"; char path[512]; grossezahl[0] = 12; grossezahl[2] = 23; #if HAVE_LONG_LONG_INT grossezahl[1] = (int64_t)555555555555LL; grossezahl[3] = (int64_t)777777777777LL; #else grossezahl[1] = (int64_t)555555555555; grossezahl[3] = (int64_t)777777777777; #endif /* HAVE_LONG_LONG_INT */ if(strstr(argv[0],"napi_test-hdf5") != NULL){ nx_creation_code = NXACC_CREATE5; strcpy(nxFile,"NXtest.h5"); }else if(strstr(argv[0],"napi_test-xml-table") != NULL){ nx_creation_code = NXACC_CREATEXML | NXACC_TABLE; strcpy(nxFile,"NXtest-table.xml"); }else if(strstr(argv[0],"napi_test-xml") != NULL){ nx_creation_code = NXACC_CREATEXML; strcpy(nxFile,"NXtest.xml"); } else { nx_creation_code = NXACC_CREATE; strcpy(nxFile,"NXtest.hdf"); } /* create file */ if (NXopen (nxFile, nx_creation_code, &fileid) != NX_OK) return 1; if (nx_creation_code == NXACC_CREATE5) { if (NXreopen (fileid, &clone_fileid) != NX_OK) return 1; } NXsetnumberformat(fileid,NX_FLOAT32,"%9.3f"); if (NXmakegroup (fileid, "entry", "NXentry") != NX_OK) return 1; if (NXopengroup (fileid, "entry", "NXentry") != NX_OK) return 1; if(NXputattr(fileid,"hugo","namenlos",strlen("namenlos"), NX_CHAR) != NX_OK) return 1; if(NXputattr(fileid,"cucumber","passion",strlen("passion"), NX_CHAR) != NX_OK) return 1; NXlen = strlen(ch_test_data); if (NXmakedata (fileid, "ch_data", NX_CHAR, 1, &NXlen) != NX_OK) return 1; if (NXopendata (fileid, "ch_data") != NX_OK) return 1; if (NXputdata (fileid, ch_test_data) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXmakedata (fileid, "c1_data", NX_CHAR, 2, array_dims) != NX_OK) return 1; if (NXopendata (fileid, "c1_data") != NX_OK) return 1; if (NXputdata (fileid, c1_array) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXmakedata (fileid, "i1_data", NX_INT8, 1, &array_dims[1]) != NX_OK) return 1; if (NXopendata (fileid, "i1_data") != NX_OK) return 1; if (NXputdata (fileid, i1_array) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXmakedata (fileid, "i2_data", NX_INT16, 1, &array_dims[1]) != NX_OK) return 1; if (NXopendata (fileid, "i2_data") != NX_OK) return 1; if (NXputdata (fileid, i2_array) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXmakedata (fileid, "i4_data", NX_INT32, 1, &array_dims[1]) != NX_OK) return 1; if (NXopendata (fileid, "i4_data") != NX_OK) return 1; if (NXputdata (fileid, i4_array) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXcompmakedata (fileid, "r4_data", NX_FLOAT32, 2, array_dims,NX_COMP_LZW,chunk_size) != NX_OK) return 1; if (NXopendata (fileid, "r4_data") != NX_OK) return 1; if (NXputdata (fileid, r4_array) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXmakedata (fileid, "r8_data", NX_FLOAT64, 2, array_dims) != NX_OK) return 1; if (NXopendata (fileid, "r8_data") != NX_OK) return 1; slab_start[0] = 4; slab_start[1] = 0; slab_size[0] = 1; slab_size[1] = 4; if (NXputslab (fileid, (double*)r8_array + 16, slab_start, slab_size) != NX_OK) return 1; slab_start[0] = 0; slab_start[1] = 0; slab_size[0] = 4; slab_size[1] = 4; if (NXputslab (fileid, r8_array, slab_start, slab_size) != NX_OK) return 1; if (NXputattr (fileid, "ch_attribute", ch_test_data, strlen (ch_test_data), NX_CHAR) != NX_OK) return 1; i = 42; if (NXputattr (fileid, "i4_attribute", &i, 1, NX_INT32) != NX_OK) return 1; r = 3.14159265; if (NXputattr (fileid, "r4_attribute", &r, 1, NX_FLOAT32) != NX_OK) return 1; if (NXgetdataID (fileid, &dlink) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; dims[0] = 4; if (nx_creation_code != NXACC_CREATE) { if (NXmakedata (fileid, "grosse_zahl", NX_INT64, 1,dims) == NX_OK) { if (NXopendata (fileid, "grosse_zahl") != NX_OK) return 1; if (NXputdata (fileid, grossezahl) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; } } if (NXmakegroup (fileid, "data", "NXdata") != NX_OK) return 1; if (NXopengroup (fileid, "data", "NXdata") != NX_OK) return 1; if (NXmakelink (fileid, &dlink) != NX_OK) return 1; dims[0] = 100; dims[1] = 20; for(i = 0; i < 100; i++) { for(j = 0; j < 20; j++) { comp_array[i][j] = i; } } cdims[0] = 20; cdims[1] = 20; if (NXcompmakedata (fileid, "comp_data", NX_INT32, 2, dims, NX_COMP_LZW, cdims) != NX_OK) return 1; if (NXopendata (fileid, "comp_data") != NX_OK) return 1; if (NXputdata (fileid, comp_array) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXflush (&fileid) != NX_OK) return 1; if (NXmakedata (fileid, "flush_data", NX_INT32, 1, unlimited_dims) != NX_OK) return 1; slab_size[0] = 1; for (i = 0; i < 7; i++) { slab_start[0] = i; if (NXopendata (fileid, "flush_data") != NX_OK) return 1; if (NXputslab (fileid, &i, slab_start, slab_size) != NX_OK) return 1; if (NXflush (&fileid) != NX_OK) return 1; } if (NXclosegroup (fileid) != NX_OK) return 1; if (NXmakegroup (fileid, "sample", "NXsample") != NX_OK) return 1; if (NXopengroup (fileid, "sample", "NXsample") != NX_OK) return 1; NXlen = 12; if (NXmakedata (fileid, "ch_data", NX_CHAR, 1, &NXlen) != NX_OK) return 1; if (NXopendata (fileid, "ch_data") != NX_OK) return 1; if (NXputdata (fileid, "NeXus sample") != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXgetgroupID (fileid, &glink) != NX_OK) return 1; if (( nx_creation_code & NXACC_CREATEXML) == 0 ) { if (NXmakedata (fileid, "cdata_unlimited", NX_CHAR, 2, unlimited_cdims) != NX_OK) return 1; if (NXopendata (fileid, "cdata_unlimited") != NX_OK) return 1; slab_size[0] = 1; slab_size[1] = 4; slab_start[1] = 0; for (i = 0; i < 5; i++) { slab_start[0] = i; if (NXputslab (fileid, &(c1_array[i][0]), slab_start, slab_size) != NX_OK) return 1; } if (NXclosedata (fileid) != NX_OK) return 1; } if (NXclosegroup (fileid) != NX_OK) return 1; if (NXclosegroup (fileid) != NX_OK) return 1; if (NXmakegroup (fileid, "link", "NXentry") != NX_OK) return 1; if (NXopengroup (fileid, "link", "NXentry") != NX_OK) return 1; if (NXmakelink (fileid, &glink) != NX_OK) return 1; if (NXmakenamedlink (fileid,"renLinkGroup", &glink) != NX_OK) return 1; if (NXmakenamedlink (fileid, "renLinkData", &dlink) != NX_OK) return 1; if (NXclosegroup (fileid) != NX_OK) return 1; if (NXclose (&fileid) != NX_OK) return 1; if ( (argc >= 2) && !strcmp(argv[1], "-q") ) { return 0; /* create only */ } /* read test */ if (NXopen (nxFile, NXACC_RDWR,&fileid) != NX_OK) return 1; if(NXinquirefile(fileid,filename,256) != NX_OK){ return 1; } printf("NXinquirefile found: %s\n", relativePathOf(filename)); NXgetattrinfo (fileid, &i); if (i > 0) { printf ("Number of global attributes: %d\n", i); } do { attr_status = NXgetnextattr (fileid, name, NXdims, &NXtype); if (attr_status == NX_ERROR) return 1; if (attr_status == NX_OK) { switch (NXtype) { case NX_CHAR: NXlen = sizeof (char_buffer); if (NXgetattr (fileid, name, char_buffer, &NXlen, &NXtype) != NX_OK) return 1; if ( strcmp(name, "file_time") && strcmp(name, "HDF_version") && strcmp(name, "HDF5_Version") && strcmp(name, "XML_version") ) { printf (" %s = %s\n", name, char_buffer); } break; } } } while (attr_status == NX_OK); if (NXopengroup (fileid, "entry", "NXentry") != NX_OK) return 1; NXgetattrinfo(fileid,&i); printf("Number of group attributes: %d\n", i); if(NXgetpath(fileid,path,512) != NX_OK)return 1; printf("NXentry path %s\n", path); do { attr_status = NXgetnextattr (fileid, name, NXdims, &NXtype); if (attr_status == NX_ERROR) return 1; if (attr_status == NX_OK) { switch (NXtype) { case NX_CHAR: NXlen = sizeof (char_buffer); if (NXgetattr (fileid, name, char_buffer, &NXlen, &NXtype) != NX_OK) return 1; printf (" %s = %s\n", name, char_buffer); } } } while (attr_status == NX_OK); if (NXgetgroupinfo (fileid, &i, group_name, class_name) != NX_OK) return 1; printf ("Group: %s(%s) contains %d items\n", group_name, class_name, i); do { entry_status = NXgetnextentry (fileid, name, char_class, &NXtype); if (entry_status == NX_ERROR) return 1; if (strcmp(char_class,"SDS") != 0) { if (entry_status != NX_EOD) { printf (" Subgroup: %s(%s)\n", name, char_class); entry_status = NX_OK; } } else { if (entry_status == NX_OK) { if (NXopendata (fileid, name) != NX_OK) return 1; if(NXgetpath(fileid,path,512) != NX_OK)return 1; printf("Data path %s\n", path); if (NXgetinfo (fileid, &NXrank, NXdims, &NXtype) != NX_OK) return 1; printf (" %s(%d)", name, NXtype); if (NXmalloc ((void **) &data_buffer, NXrank, NXdims, NXtype) != NX_OK) return 1; n = 1; for(k=0; k<NXrank; k++) { n *= NXdims[k]; } if (NXtype == NX_CHAR) { if (NXgetdata (fileid, data_buffer) != NX_OK) return 1; print_data (" = ", data_buffer, NXtype, n); } else if (NXtype != NX_FLOAT32 && NXtype != NX_FLOAT64) { if (NXgetdata (fileid, data_buffer) != NX_OK) return 1; print_data (" = ", data_buffer, NXtype, n); } else { slab_start[0] = 0; slab_start[1] = 0; slab_size[0] = 1; slab_size[1] = 4; if (NXgetslab (fileid, data_buffer, slab_start, slab_size) != NX_OK) return 1; print_data ("\n ", data_buffer, NXtype, 4); slab_start[0] = 1; if (NXgetslab (fileid, data_buffer, slab_start, slab_size) != NX_OK) return 1; print_data (" ", data_buffer, NXtype, 4); slab_start[0] = 2; if (NXgetslab (fileid, data_buffer, slab_start, slab_size) != NX_OK) return 1; print_data (" ", data_buffer, NXtype, 4); slab_start[0] = 3; if (NXgetslab (fileid, data_buffer, slab_start, slab_size) != NX_OK) return 1; print_data (" ", data_buffer, NXtype, 4); slab_start[0] = 4; if (NXgetslab (fileid, data_buffer, slab_start, slab_size) != NX_OK) return 1; print_data (" ", data_buffer, NXtype, 4); if (NXgetattrinfo (fileid, &i) != NX_OK) return 1; if (i > 0) { printf (" Number of attributes : %d\n", i); } do { attr_status = NXgetnextattr (fileid, name, NXdims, &NXtype); if (attr_status == NX_ERROR) return 1; if (attr_status == NX_OK) { switch (NXtype) { case NX_INT32: NXlen = 1; if (NXgetattr (fileid, name, &i, &NXlen, &NXtype) != NX_OK) return 1; printf (" %s : %d\n", name, i); break; case NX_FLOAT32: NXlen = 1; if (NXgetattr (fileid, name, &r, &NXlen, &NXtype) != NX_OK) return 1; printf (" %s : %f\n", name, r); break; case NX_CHAR: NXlen = sizeof (char_buffer); if (NXgetattr (fileid, name, char_buffer, &NXlen, &NXtype) != NX_OK) return 1; printf (" %s : %s\n", name, char_buffer); break; } } } while (attr_status == NX_OK); } if (NXclosedata (fileid) != NX_OK) return 1; if (NXfree ((void **) &data_buffer) != NX_OK) return 1; } } } while (entry_status == NX_OK); if (NXclosegroup (fileid) != NX_OK) return 1; /* * check links */ if (NXopengroup (fileid, "entry", "NXentry") != NX_OK) return 1; if (NXopengroup (fileid, "sample", "NXsample") != NX_OK) return 1; if (NXgetgroupID (fileid, &glink) != NX_OK) return 1; if (NXclosegroup (fileid) != NX_OK) return 1; if (NXopengroup (fileid, "data", "NXdata") != NX_OK) return 1; if (NXopendata (fileid, "r8_data") != NX_OK) return 1; if (NXgetdataID (fileid, &dlink) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXclosegroup (fileid) != NX_OK) return 1; if (NXopendata (fileid, "r8_data") != NX_OK) return 1; if (NXgetdataID (fileid, &blink) != NX_OK) return 1; if (NXclosedata (fileid) != NX_OK) return 1; if (NXsameID(fileid, &dlink, &blink) != NX_OK) { printf ("Link check FAILED (r8_data)\n"); printf ("original data\n"); NXIprintlink(fileid, &dlink); printf ("linked data\n"); NXIprintlink(fileid, &blink); return 1; } if (NXclosegroup (fileid) != NX_OK) return 1; if (NXopengroup (fileid, "link", "NXentry") != NX_OK) return 1; if (NXopengroup (fileid, "sample", "NXsample") != NX_OK) return 1; if(NXgetpath(fileid,path,512) != NX_OK)return 1; printf("Group path %s\n", path); if (NXgetgroupID (fileid, &blink) != NX_OK) return 1; if (NXsameID(fileid, &glink, &blink) != NX_OK) { printf ("Link check FAILED (sample)\n"); printf ("original group\n"); NXIprintlink(fileid, &glink); printf ("linked group\n"); NXIprintlink(fileid, &blink); return 1; } if (NXclosegroup (fileid) != NX_OK) return 1; if (NXopengroup (fileid, "renLinkGroup", "NXsample") != NX_OK) return 1; if (NXgetgroupID (fileid, &blink) != NX_OK) return 1; if (NXsameID(fileid, &glink, &blink) != NX_OK) { printf ("Link check FAILED (renLinkGroup)\n"); printf ("original group\n"); NXIprintlink(fileid, &glink); printf ("linked group\n"); NXIprintlink(fileid, &blink); return 1; } if (NXclosegroup (fileid) != NX_OK) return 1; if(NXopendata(fileid,"renLinkData") != NX_OK) return 1; if(NXgetdataID(fileid,&blink) != NX_OK) return 1; if (NXsameID(fileid, &dlink, &blink) != NX_OK) { printf ("Link check FAILED (renLinkData)\n"); printf ("original group\n"); NXIprintlink(fileid, &glink); printf ("linked group\n"); NXIprintlink(fileid, &blink); return 1; } if(NXclosedata(fileid) != NX_OK) return 1; if (NXclosegroup (fileid) != NX_OK) return 1; printf ("Link check OK\n"); /* tests for NXopenpath */ if(NXopenpath(fileid,"/entry/data/comp_data") != NX_OK){ printf("Failure on NXopenpath\n"); return 0; } if(NXopenpath(fileid,"/entry/data/comp_data") != NX_OK){ printf("Failure on NXopenpath\n"); return 0; } if(NXopenpath(fileid,"../r8_data") != NX_OK){ printf("Failure on NXopenpath\n"); return 0; } if(NXopengrouppath(fileid,"/entry/data/comp_data") != NX_OK){ printf("Failure on NXopengrouppath\n"); return 0; } if(NXopenpath(fileid,"/entry/data/r8_data") != NX_OK){ printf("Failure on NXopenpath\n"); return 0; } printf("NXopenpath checks OK\n"); if (NXclose (&fileid) != NX_OK) return 1; printf("before load path tests\n"); if(testLoadPath() != 0) return 1; printf("before external link tests\n"); if(testExternal(argv[0]) != 0) { return 1; } printf("all ok - done\n"); return 0; }
/*---------------------------------------------------------------------*/ static int testExternal(char *progName){ char nxfile[255], ext[5], testFile[80], time[132], filename[256]; int create; NXhandle hfil; int dummylen = 1; float dummyfloat = 1; float temperature; if(strstr(progName,"hdf4") != NULL){ strcpy(ext,"hdf"); create = NXACC_CREATE; } else if(strstr(progName,"hdf5") != NULL){ strcpy(ext,"h5"); create = NXACC_CREATE5; } else if(strstr(progName,"xml") != NULL){ strcpy(ext,"xml"); create = NXACC_CREATEXML; } else { printf("Failed to recognise napi_test program in testExternal\n"); return 1; } sprintf(testFile,"nxext.%s", ext); /* create the test file */ if(NXopen(testFile,create,&hfil) != NX_OK){ return 1; } /*if(NXmakegroup(hfil,"entry1","NXentry") != NX_OK){ return 1; }*/ sprintf(nxfile,"nxfile://data/dmc01.%s#/entry1",ext); if(NXlinkexternal(hfil,"entry1","NXentry",nxfile) != NX_OK){ return 1; } /*if(NXmakegroup(hfil,"entry2","NXentry") != NX_OK){ return 1; }*/ sprintf(nxfile,"nxfile://data/dmc02.%s#/entry1",ext); if(NXlinkexternal(hfil,"entry2","NXentry",nxfile) != NX_OK){ return 1; } if(NXmakegroup(hfil,"entry3","NXentry") != NX_OK){ return 1; } if(NXopengroup(hfil,"entry3","NXentry") != NX_OK){ return 1; } /* force create old style external link */ if (NXmakedata (hfil, "extlinkdata", NX_FLOAT32, 1, &dummylen) != NX_OK) return 1; if (NXopendata (hfil, "extlinkdata") != NX_OK) return 1; if (NXputdata (hfil, &dummyfloat) != NX_OK) return 1; sprintf(nxfile,"nxfile://data/dmc01.%s#/entry1/sample/temperature_mean",ext); if(NXputattr(hfil,"napimount",nxfile,strlen(nxfile), NX_CHAR) != NX_OK) return 1; /* this would segfault because we are tricking the napi stack if(NXclosedata(&hfil) != NX_OK){ return 1; } */ if(NXopenpath(hfil,"/entry3") != NX_OK){ return 1; } /* create new style external link on hdf5 , equivalent to the above on other backends */ if (NXlinkexternaldataset(hfil, "extlinknative", nxfile) != NX_OK) return 1; if(NXclose(&hfil) != NX_OK){ return 1; } /* actually test linking */ if(NXopen(testFile,NXACC_RDWR,&hfil) != NX_OK){ return 1; } if(NXopenpath(hfil,"/entry1/start_time") != NX_OK){ return 1; } memset(time,0,132); if(NXgetdata(hfil,time) != NX_OK){ return 1; } printf("First file time: %s\n", time); if(NXinquirefile(hfil,filename,256) != NX_OK){ return 1; } printf("NXinquirefile found: %s\n", relativePathOf(filename)); if(NXopenpath(hfil,"/entry2/sample/sample_name") != NX_OK){ return 1; } memset(time,0,132); if(NXgetdata(hfil,time) != NX_OK){ return 1; } printf("Second file sample: %s\n", time); if(NXinquirefile(hfil,filename,256) != NX_OK){ return 1; } printf("NXinquirefile found: %s\n", relativePathOf(filename)); if(NXopenpath(hfil,"/entry2/start_time") != NX_OK){ return 1; } memset(time,0,132); if(NXgetdata(hfil,time) != NX_OK){ return 1; } printf("Second file time: %s\n", time); NXopenpath(hfil,"/"); if(NXisexternalgroup(hfil,"entry1","NXentry",filename,255) != NX_OK){ return 1; } else { printf("entry1 external URL = %s\n", filename); } printf("testing link to external data set\n"); if(NXopenpath(hfil,"/entry3") != NX_OK){ return 1; } if(NXisexternaldataset(hfil,"extlinkdata",filename,255) != NX_OK){ printf("extlinkdata should be external link\n"); return 1; } else { printf("extlinkdata external URL = %s\n", filename); } if (NXopendata (hfil, "extlinkdata") != NX_OK) return 1; memset(&temperature,0,4); if(NXgetdata(hfil,&temperature) != NX_OK){ return 1; } printf("value retrieved: %4.2f\n", temperature); if(NXopenpath(hfil,"/entry3") != NX_OK){ return 1; } if(NXisexternaldataset(hfil,"extlinknative",filename,255) != NX_OK){ printf("extlinknative should be external link\n"); return 1; } else { printf("extlinknative external URL = %s\n", filename); } if (NXopendata (hfil, "extlinknative") != NX_OK) return 1; memset(&temperature,0,4); if(NXgetdata(hfil,&temperature) != NX_OK){ return 1; } printf("value retrieved: %4.2f\n", temperature); NXclose(&hfil); printf("External File Linking tested OK\n"); return 0; }
int NDFileNexus::processNode(TiXmlNode *curNode, NDArray *pArray) { int status = 0; const char *nodeName; const char *nodeValue; const char *nodeOuttype; const char *nodeSource; const char *nodeType; //float data; int rank; NDDataType_t type; int ii; int dims[ND_ARRAY_MAX_DIMS]; int numCapture; int fileWriteMode; NDAttrDataType_t attrDataType; NDAttribute *pAttr; size_t attrDataSize; size_t nodeTextLen; int wordSize; int dataOutType=NDInt8; size_t numWords; int numItems = 0; int addr =0; void *pValue; char nodeText[256]; NXname dataclass; NXname dPath; static const char *functionName = "processNode"; asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "Entering %s:%s\n", driverName, functionName ); /* Must lock when accessing parameter library */ this->lock(); getIntegerParam(addr, NDFileWriteMode, &fileWriteMode); getIntegerParam(addr, NDFileNumCapture, &numCapture); this->unlock(); nodeValue = curNode->Value(); asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER, "%s:%s Value=%s Type=%d\n", driverName, functionName, curNode->Value(), curNode->Type()); nodeType = curNode->ToElement()->Attribute("type"); NXstatus stat; if (strcmp (nodeValue, "NXroot") == 0) { this->iterateNodes(curNode, pArray); } /* only include all the NeXus base classes */ else if ((strcmp (nodeValue, "NXentry") ==0) || (strcmp (nodeValue, "NXinstrument") ==0) || (strcmp (nodeValue, "NXsample") ==0) || (strcmp (nodeValue, "NXmonitor") ==0) || (strcmp (nodeValue, "NXsource") ==0) || (strcmp (nodeValue, "NXuser") ==0) || (strcmp (nodeValue, "NXdata") ==0) || (strcmp (nodeValue, "NXdetector") ==0) || (strcmp (nodeValue, "NXaperature") ==0) || (strcmp (nodeValue, "NXattenuator") ==0) || (strcmp (nodeValue, "NXbeam_stop") ==0) || (strcmp (nodeValue, "NXbending_magnet") ==0) || (strcmp (nodeValue, "NXcollimator") ==0) || (strcmp (nodeValue, "NXcrystal") ==0) || (strcmp (nodeValue, "NXdisk_chopper") ==0) || (strcmp (nodeValue, "NXfermi_chopper") ==0) || (strcmp (nodeValue, "NXfilter") ==0) || (strcmp (nodeValue, "NXflipper") ==0) || (strcmp (nodeValue, "NXguide") ==0) || (strcmp (nodeValue, "NXinsertion_device") ==0) || (strcmp (nodeValue, "NXmirror") ==0) || (strcmp (nodeValue, "NXmoderator") ==0) || (strcmp (nodeValue, "NXmonochromator") ==0) || (strcmp (nodeValue, "NXpolarizer") ==0) || (strcmp (nodeValue, "NXpositioner") ==0) || (strcmp (nodeValue, "NXvelocity_selector") ==0) || (strcmp (nodeValue, "NXevent_data") ==0) || (strcmp (nodeValue, "NXprocess") ==0) || (strcmp (nodeValue, "NXcharacterization") ==0) || (strcmp (nodeValue, "NXlog") ==0) || (strcmp (nodeValue, "NXnote") ==0) || (strcmp (nodeValue, "NXbeam") ==0) || (strcmp (nodeValue, "NXgeometry") ==0) || (strcmp (nodeValue, "NXtranslation") ==0) || (strcmp (nodeValue, "NXshape") ==0) || (strcmp (nodeValue, "NXorientation") ==0) || (strcmp (nodeValue, "NXenvironment") ==0) || (strcmp (nodeValue, "NXsensor") ==0) || (strcmp (nodeValue, "NXcapillary") ==0) || (strcmp (nodeValue, "NXcollection") ==0) || (strcmp (nodeValue, "NXdetector_group") ==0) || (strcmp (nodeValue, "NXparameters") ==0) || (strcmp (nodeValue, "NXsubentry") ==0) || (strcmp (nodeValue, "NXxraylens") ==0) || (nodeType && strcmp (nodeType, "UserGroup") == 0) ) { nodeName = curNode->ToElement()->Attribute("name"); if (nodeName == NULL) { nodeName = nodeValue; } stat = NXmakegroup(this->nxFileHandle, (const char *)nodeName, (const char *)nodeValue); stat |= NXopengroup(this->nxFileHandle, (const char *)nodeName, (const char *)nodeValue); if (stat != NX_OK ) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s Error creating group %s %s\n", driverName, functionName, nodeName, nodeValue); } this->iterateNodes(curNode, pArray); stat = NXclosegroup(this->nxFileHandle); if (stat != NX_OK ) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s Error closing group %s %s\n", driverName, functionName, nodeName, nodeValue); } } else if (strcmp (nodeValue, "Attr") ==0) { nodeName = curNode->ToElement()->Attribute("name"); nodeSource = curNode->ToElement()->Attribute("source"); if (nodeType && strcmp(nodeType, "ND_ATTR") == 0 ) { pAttr = this->pFileAttributes->find(nodeSource); if (pAttr != NULL ){ pAttr->getValueInfo(&attrDataType, &attrDataSize); this->getAttrTypeNSize(pAttr, &dataOutType, &wordSize); if (dataOutType > 0) { pValue = calloc( attrDataSize, wordSize ); pAttr->getValue(attrDataType, (char *)pValue, attrDataSize*wordSize); NXputattr(this->nxFileHandle, nodeName, pValue, (int)(attrDataSize/wordSize), dataOutType); free(pValue); } } else { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s Could not find attribute named %s\n", driverName, functionName, nodeSource); } } else if (nodeType && strcmp(nodeType, "CONST") == 0 ) { this->findConstText( curNode, nodeText); nodeOuttype = curNode->ToElement()->Attribute("outtype"); if (nodeOuttype == NULL){ nodeOuttype = "NX_CHAR"; } dataOutType = this->typeStringToVal((const char *)nodeOuttype); if ( dataOutType == NX_CHAR ) { nodeTextLen = strlen(nodeText); } else { nodeTextLen = 1; } pValue = allocConstValue( dataOutType, nodeTextLen); constTextToDataType(nodeText, dataOutType, pValue); NXputattr(this->nxFileHandle, nodeName, pValue, (int)nodeTextLen, dataOutType); free(pValue); } else if (nodeType) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s Node type %s for node %s is invalid\n", driverName, functionName, nodeType, nodeValue); } } else { nodeSource = curNode->ToElement()->Attribute("source"); if (nodeType && strcmp(nodeType, "ND_ATTR") == 0 ) { pAttr = this->pFileAttributes->find(nodeSource); if ( pAttr != NULL) { pAttr->getValueInfo(&attrDataType, &attrDataSize); this->getAttrTypeNSize(pAttr, &dataOutType, &wordSize); if (dataOutType > 0) { pValue = calloc( attrDataSize, wordSize ); pAttr->getValue(attrDataType, (char *)pValue, attrDataSize); numWords = attrDataSize/wordSize; NXmakedata( this->nxFileHandle, nodeValue, dataOutType, 1, (int *)&(numWords)); NXopendata(this->nxFileHandle, nodeValue); NXputdata(this->nxFileHandle, (char *)pValue); free(pValue); this->iterateNodes(curNode, pArray); NXclosedata(this->nxFileHandle); } } else { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s Could not add node %s could not find an attribute by that name\n", driverName, functionName, nodeSource); } } else if (nodeType && strcmp(nodeType, "pArray") == 0 ){ rank = pArray->ndims; type = pArray->dataType; for (ii=0; ii<rank; ii++) { dims[(rank-1) - ii] = (int)pArray->dims[ii].size; } switch(type) { case NDInt8: dataOutType = NX_INT8; wordSize = 1; break; case NDUInt8: dataOutType = NX_UINT8; wordSize = 1; break; case NDInt16: dataOutType = NX_INT16; wordSize = 2; break; case NDUInt16: dataOutType = NX_UINT16; wordSize = 2; break; case NDInt32: dataOutType = NX_INT32; wordSize = 4; break; case NDUInt32: dataOutType = NX_UINT32; wordSize = 4; break; case NDFloat32: dataOutType = NX_FLOAT32; wordSize = 4; break; case NDFloat64: dataOutType = NX_FLOAT64; wordSize = 8; break; } asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER, "%s:%s Starting to write data making group\n", driverName, functionName ); if ( fileWriteMode == NDFileModeSingle ) { NXmakedata( this->nxFileHandle, nodeValue, dataOutType, rank, dims); } else if ((fileWriteMode == NDFileModeCapture) || (fileWriteMode == NDFileModeStream)) { for (ii = 0; ii < rank; ii++) { dims[(rank) - ii] = dims[(rank-1) - ii]; } rank = rank +1; dims[0] = numCapture; NXmakedata( this->nxFileHandle, nodeValue, dataOutType, rank, dims); } dPath[0] = '\0'; dataclass[0] = '\0'; NXopendata(this->nxFileHandle, nodeValue); // If you are having problems with NXgetgroupinfo in Visual Studio, // Checkout this link: http://trac.nexusformat.org/code/ticket/217 // Fixed in Nexus 4.2.1 //printf("%s:%s: calling NXgetgroupinfo!\n", driverName, functionName); NXgetgroupinfo(this->nxFileHandle, &numItems, dPath, dataclass); //printf("dPath=%s, nodeValue=%s\n", dPath, nodeValue ); sprintf(this->dataName, "%s", nodeValue); sprintf(this->dataPath, "%c%s", '/', dPath); this->iterateNodes(curNode, pArray); NXclosedata(this->nxFileHandle); } else if (nodeType && strcmp(nodeType, "CONST") == 0 ){ this->findConstText( curNode, nodeText); nodeOuttype = curNode->ToElement()->Attribute("outtype"); if (nodeOuttype == NULL){ nodeOuttype = "NX_CHAR"; } dataOutType = this->typeStringToVal(nodeOuttype); if ( dataOutType == NX_CHAR ) { nodeTextLen = strlen(nodeText); } else { nodeTextLen = 1; } pValue = allocConstValue( dataOutType, nodeTextLen); constTextToDataType(nodeText, dataOutType, pValue); NXmakedata( this->nxFileHandle, nodeValue, dataOutType, 1, (int *)&nodeTextLen); NXopendata(this->nxFileHandle, nodeValue); NXputdata(this->nxFileHandle, pValue); free(pValue); this->iterateNodes(curNode, pArray); NXclosedata(this->nxFileHandle); } else if (nodeType) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s Node type %s for node %s is invalid\n", driverName, functionName, nodeType, nodeValue); } else { this->findConstText( curNode, nodeText); dataOutType = NX_CHAR; nodeTextLen = strlen(nodeText); if (nodeTextLen == 0) { sprintf(nodeText, "LEFT BLANK"); nodeTextLen = strlen(nodeText); } pValue = allocConstValue( dataOutType, nodeTextLen); constTextToDataType(nodeText, dataOutType, pValue); NXmakedata( this->nxFileHandle, nodeValue, dataOutType, 1, (int *)&nodeTextLen); NXopendata(this->nxFileHandle, nodeValue); NXputdata(this->nxFileHandle, pValue); this->iterateNodes(curNode, pArray); NXclosedata(this->nxFileHandle); } } asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "Leaving %s:%s\n", driverName, functionName ); return (status); }
/** Write out a table Workspace's */ int NexusFileIO::writeNexusTableWorkspace( const API::ITableWorkspace_const_sptr& itableworkspace, const char * group_name) const { NXstatus status = 0; boost::shared_ptr<const TableWorkspace> tableworkspace = boost::dynamic_pointer_cast<const TableWorkspace>(itableworkspace); boost::shared_ptr<const PeaksWorkspace> peakworkspace = boost::dynamic_pointer_cast<const PeaksWorkspace>(itableworkspace); if ( !tableworkspace && !peakworkspace ) return((status==NX_ERROR)?3:0); //write data entry status=NXmakegroup(fileID,group_name,"NXdata"); if(status==NX_ERROR) return(2); NXopengroup(fileID,group_name,"NXdata"); int nRows = static_cast<int>(itableworkspace->rowCount()); int dims_array[1] = { nRows }; for (size_t i = 0; i < itableworkspace->columnCount(); i++) { Column_const_sptr col = itableworkspace->getColumn(i); std::string str = "column_" + boost::lexical_cast<std::string>(i+1); if ( col->isType<double>() ) { double * toNexus = new double[nRows]; for (int ii = 0; ii < nRows; ii++) toNexus[ii] = col->cell<double>(ii); NXwritedata(str.c_str(), NX_FLOAT64, 1, dims_array, (void *)(toNexus), false); delete[] toNexus; // attributes NXopendata(fileID, str.c_str()); std::string units = "Not known"; std::string interpret_as = "A double"; NXputattr(fileID, "units", reinterpret_cast<void*>(const_cast<char*>(units.c_str())), static_cast<int>(units.size()), NX_CHAR); NXputattr(fileID, "interpret_as", reinterpret_cast<void*>(const_cast<char*>(interpret_as.c_str())), static_cast<int>(interpret_as.size()), NX_CHAR); NXclosedata(fileID); } else if ( col->isType<int>() ) { int * toNexus = new int[nRows]; for (int ii = 0; ii < nRows; ii++) toNexus[ii] = col->cell<int>(ii); NXwritedata(str.c_str(), NX_INT32, 1, dims_array, (void *)(toNexus), false); delete[] toNexus; // attributes NXopendata(fileID, str.c_str()); std::string units = "Not known"; std::string interpret_as = "An integer"; NXputattr(fileID, "units", reinterpret_cast<void*>(const_cast<char*>(units.c_str())), static_cast<int>(units.size()), NX_CHAR); NXputattr(fileID, "interpret_as", reinterpret_cast<void*>(const_cast<char*>(interpret_as.c_str())), static_cast<int>(interpret_as.size()), NX_CHAR); NXclosedata(fileID); } else if ( col->isType<std::string>() ) { // determine max string size size_t maxStr = 0; for (int ii = 0; ii < nRows; ii++) { if ( col->cell<std::string>(ii).size() > maxStr) maxStr = col->cell<std::string>(ii).size(); } int dims_array[2] = { nRows, static_cast<int>(maxStr) }; int asize[2]={1,dims_array[1]}; NXcompmakedata(fileID, str.c_str(), NX_CHAR, 2, dims_array,false,asize); NXopendata(fileID, str.c_str()); char* toNexus = new char[maxStr*nRows]; for(int ii = 0; ii < nRows; ii++) { std::string rowStr = col->cell<std::string>(ii); for (size_t ic = 0; ic < rowStr.size(); ic++) toNexus[ii*maxStr+ic] = rowStr[ic]; for (size_t ic = rowStr.size(); ic < static_cast<size_t>(maxStr); ic++) toNexus[ii*maxStr+ic] = ' '; } NXputdata(fileID, (void *)(toNexus)); delete[] toNexus; // attributes std::string units = "N/A"; std::string interpret_as = "A string"; NXputattr(fileID, "units", reinterpret_cast<void*>(const_cast<char*>(units.c_str())), static_cast<int>(units.size()), NX_CHAR); NXputattr(fileID, "interpret_as", reinterpret_cast<void*>(const_cast<char*>(interpret_as.c_str())), static_cast<int>(interpret_as.size()), NX_CHAR); NXclosedata(fileID); } #define IF_VECTOR_COLUMN(Type, NexusType) \ else if ( col->isType< std::vector<Type> >() ) \ { \ auto vecCol = boost::dynamic_pointer_cast< const VectorColumn<Type> >(col); \ writeNexusVectorColumn<Type>(vecCol, str, NexusType, #Type); \ } IF_VECTOR_COLUMN(int,NX_INT32) IF_VECTOR_COLUMN(double,NX_FLOAT64) // write out title NXopendata(fileID, str.c_str()); NXputattr(fileID, "name", reinterpret_cast<void*>(const_cast<char*>(col->name().c_str())), static_cast<int>(col->name().size()), NX_CHAR); NXclosedata(fileID); } status=NXclosegroup(fileID); return((status==NX_ERROR)?3:0); }
/** Write out a MatrixWorkspace's data as a 2D matrix. * Use writeNexusProcessedDataEvent if writing an EventWorkspace. */ int NexusFileIO::writeNexusProcessedData2D( const API::MatrixWorkspace_const_sptr& localworkspace, const bool& uniformSpectra, const std::vector<int>& spec, const char * group_name, bool write2Ddata) const { NXstatus status; //write data entry status=NXmakegroup(fileID,group_name,"NXdata"); if(status==NX_ERROR) return(2); NXopengroup(fileID,group_name,"NXdata"); // write workspace data const size_t nHist=localworkspace->getNumberHistograms(); if(nHist<1) return(2); const size_t nSpectBins=localworkspace->readY(0).size(); const size_t nSpect=spec.size(); int dims_array[2] = { static_cast<int>(nSpect),static_cast<int>(nSpectBins) }; // Set the axis labels and values Mantid::API::Axis *xAxis=localworkspace->getAxis(0); Mantid::API::Axis *sAxis=localworkspace->getAxis(1); std::string xLabel,sLabel; if ( xAxis->isSpectra() ) xLabel = "spectraNumber"; else { if ( xAxis->unit() ) xLabel = xAxis->unit()->unitID(); else xLabel = "unknown"; } if ( sAxis->isSpectra() ) sLabel = "spectraNumber"; else { if ( sAxis->unit() ) sLabel = sAxis->unit()->unitID(); else sLabel = "unknown"; } // Get the values on the vertical axis std::vector<double> axis2; if (nSpect < nHist) for (size_t i=0;i<nSpect;i++) axis2.push_back((*sAxis)(spec[i])); else for (size_t i=0;i<sAxis->length();i++) axis2.push_back((*sAxis)(i)); int start[2]={0,0}; int asize[2]={1,dims_array[1]}; // -------------- Actually write the 2D data ---------------------------- if (write2Ddata) { std::string name="values"; NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array,m_nexuscompression,asize); NXopendata(fileID, name.c_str()); for(size_t i=0;i<nSpect;i++) { int s = spec[i]; NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readY(s)[0]))),start,asize); start[0]++; } if(m_progress != 0) m_progress->reportIncrement(1, "Writing data"); int signal=1; NXputattr (fileID, "signal", &signal, 1, NX_INT32); // More properties const std::string axesNames="axis2,axis1"; NXputattr (fileID, "axes", reinterpret_cast<void*>(const_cast<char*>(axesNames.c_str())), static_cast<int>(axesNames.size()), NX_CHAR); std::string yUnits=localworkspace->YUnit(); std::string yUnitLabel=localworkspace->YUnitLabel(); NXputattr (fileID, "units", reinterpret_cast<void*>(const_cast<char*>(yUnits.c_str())), static_cast<int>(yUnits.size()), NX_CHAR); NXputattr (fileID, "unit_label", reinterpret_cast<void*>(const_cast<char*>(yUnitLabel.c_str())), static_cast<int>(yUnitLabel.size()), NX_CHAR); NXclosedata(fileID); // error name="errors"; NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array,m_nexuscompression,asize); NXopendata(fileID, name.c_str()); start[0]=0; for(size_t i=0;i<nSpect;i++) { int s = spec[i]; NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readE(s)[0]))),start,asize); start[0]++; } if(m_progress != 0) m_progress->reportIncrement(1, "Writing data"); // Fractional area for RebinnedOutput if (localworkspace->id() == "RebinnedOutput") { RebinnedOutput_const_sptr rebin_workspace = boost::dynamic_pointer_cast<const RebinnedOutput>(localworkspace); name="frac_area"; NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array,m_nexuscompression,asize); NXopendata(fileID, name.c_str()); start[0]=0; for(size_t i=0;i<nSpect;i++) { int s = spec[i]; NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(rebin_workspace->readF(s)[0]))), start, asize); start[0]++; } if(m_progress != 0) m_progress->reportIncrement(1, "Writing data"); } NXclosedata(fileID); } // write X data, as single array or all values if "ragged" if(uniformSpectra) { dims_array[0]=static_cast<int>(localworkspace->readX(0).size()); NXmakedata(fileID, "axis1", NX_FLOAT64, 1, dims_array); NXopendata(fileID, "axis1"); NXputdata(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readX(0)[0])))); } else { dims_array[0]=static_cast<int>(nSpect); dims_array[1]=static_cast<int>(localworkspace->readX(0).size()); NXmakedata(fileID, "axis1", NX_FLOAT64, 2, dims_array); NXopendata(fileID, "axis1"); start[0]=0; asize[1]=dims_array[1]; for(size_t i=0;i<nSpect;i++) { NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readX(i)[0]))),start,asize); start[0]++; } } std::string dist=(localworkspace->isDistribution()) ? "1" : "0"; NXputattr(fileID, "distribution", reinterpret_cast<void*>(const_cast<char*>(dist.c_str())), 2, NX_CHAR); NXputattr (fileID, "units", reinterpret_cast<void*>(const_cast<char*>(xLabel.c_str())), static_cast<int>(xLabel.size()), NX_CHAR); auto label = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(xAxis->unit()); if(label) { NXputattr (fileID, "caption", reinterpret_cast<void*>(const_cast<char*>(label->caption().c_str())), static_cast<int>(label->caption().size()), NX_CHAR); auto unitLbl = label->label(); NXputattr (fileID, "label", reinterpret_cast<void*>(const_cast<char*>(unitLbl.ascii().c_str())), static_cast<int>(unitLbl.ascii().size()), NX_CHAR); } NXclosedata(fileID); if ( ! sAxis->isText() ) { // write axis2, maybe just spectra number dims_array[0]=static_cast<int>(axis2.size()); NXmakedata(fileID, "axis2", NX_FLOAT64, 1, dims_array); NXopendata(fileID, "axis2"); NXputdata(fileID, (void*)&(axis2[0])); NXputattr (fileID, "units", reinterpret_cast<void*>(const_cast<char*>(sLabel.c_str())), static_cast<int>(sLabel.size()), NX_CHAR); auto label = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(sAxis->unit()); if(label) { NXputattr (fileID, "caption", reinterpret_cast<void*>(const_cast<char*>(label->caption().c_str())), static_cast<int>(label->caption().size()), NX_CHAR); auto unitLbl = label->label(); NXputattr (fileID, "label", reinterpret_cast<void*>(const_cast<char*>(unitLbl.ascii().c_str())), static_cast<int>(unitLbl.ascii().size()), NX_CHAR); } NXclosedata(fileID); } else { std::string textAxis; for ( size_t i = 0; i < sAxis->length(); i ++ ) { std::string label = sAxis->label(i); textAxis += label + "\n"; } dims_array[0] = static_cast<int>(textAxis.size()); NXmakedata(fileID, "axis2", NX_CHAR, 2, dims_array); NXopendata(fileID, "axis2"); NXputdata(fileID, reinterpret_cast<void*>(const_cast<char*>(textAxis.c_str()))); NXputattr (fileID, "units", reinterpret_cast<void*>(const_cast<char*>("TextAxis")), 8, NX_CHAR); auto label = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(sAxis->unit()); if(label) { NXputattr (fileID, "caption", reinterpret_cast<void*>(const_cast<char*>(label->caption().c_str())), static_cast<int>(label->caption().size()), NX_CHAR); auto unitLbl = label->label(); NXputattr (fileID, "label", reinterpret_cast<void*>(const_cast<char*>(unitLbl.ascii().c_str())), static_cast<int>(unitLbl.ascii().size()), NX_CHAR); } NXclosedata(fileID); } writeNexusBinMasking(localworkspace); status=NXclosegroup(fileID); return((status==NX_ERROR)?3:0); }
/** Prints the contents of each group as XML tags and values */ int SaveToSNSHistogramNexus::WriteGroup(int is_definition) { int status, dataType, dataRank, dataDimensions[NX_MAXRANK]; NXname name, theClass; void *dataBuffer; NXlink link; do { status = NXgetnextentry(inId, name, theClass, &dataType); // std::cout << name << "(" << theClass << ")\n"; if (status == NX_ERROR) return NX_ERROR; if (status == NX_OK) { if (!strncmp(theClass, "NX", 2)) { if (NXopengroup(inId, name, theClass) != NX_OK) return NX_ERROR; add_path(name); if (NXgetgroupID(inId, &link) != NX_OK) return NX_ERROR; if (!strcmp(current_path, link.targetPath)) { // Create a copy of the group if (NXmakegroup(outId, name, theClass) != NX_OK) return NX_ERROR; if (NXopengroup(outId, name, theClass) != NX_OK) return NX_ERROR; if (WriteAttributes(is_definition) != NX_OK) return NX_ERROR; if (WriteGroup(is_definition) != NX_OK) return NX_ERROR; remove_path(name); } else { remove_path(name); strcpy(links_to_make[links_count].from, current_path); strcpy(links_to_make[links_count].to, link.targetPath); strcpy(links_to_make[links_count].name, name); links_count++; if (NXclosegroup(inId) != NX_OK) return NX_ERROR; } } else if (!strncmp(theClass, "SDS", 3)) { add_path(name); if (NXopendata(inId, name) != NX_OK) return NX_ERROR; if (NXgetdataID(inId, &link) != NX_OK) return NX_ERROR; std::string data_label(name); if (!strcmp(current_path, link.targetPath)) { // Look for the bank name std::string path(current_path); std::string bank; size_t a = path.rfind('/'); if (a != std::string::npos && a > 0) { size_t b = path.rfind('/', a - 1); if (b != std::string::npos && (b < a) && (a - b - 1) > 0) { bank = path.substr(b + 1, a - b - 1); // std::cout << current_path << ":bank " << bank << "\n"; } } //--------------------------------------------------------------------------------------- if (data_label == "data" && (bank != "")) { if (this->WriteDataGroup(bank, is_definition) != NX_OK) return NX_ERROR; ; } //--------------------------------------------------------------------------------------- else if (data_label == "time_of_flight" && (bank != "")) { // Get the original info if (NXgetinfo(inId, &dataRank, dataDimensions, &dataType) != NX_OK) return NX_ERROR; // Get the X bins const MantidVec &X = inputWorkspace->readX(0); // 1 dimension, with that number of bin boundaries dataDimensions[0] = static_cast<int>(X.size()); // The output TOF axis will be whatever size in the workspace. boost::scoped_array<float> tof_data(new float[dataDimensions[0]]); // And fill it with the X data for (size_t i = 0; i < X.size(); i++) tof_data[i] = float(X[i]); if (NXcompmakedata(outId, name, dataType, dataRank, dataDimensions, NX_COMP_LZW, dataDimensions) != NX_OK) return NX_ERROR; if (NXopendata(outId, name) != NX_OK) return NX_ERROR; if (WriteAttributes(is_definition) != NX_OK) return NX_ERROR; if (NXputdata(outId, tof_data.get()) != NX_OK) return NX_ERROR; if (NXclosedata(outId) != NX_OK) return NX_ERROR; } //--------------------------------------------------------------------------------------- else { // Everything else gets copies if (NXgetinfo(inId, &dataRank, dataDimensions, &dataType) != NX_OK) return NX_ERROR; if (NXmalloc(&dataBuffer, dataRank, dataDimensions, dataType) != NX_OK) return NX_ERROR; if (NXgetdata(inId, dataBuffer) != NX_OK) return NX_ERROR; if (NXcompmakedata(outId, name, dataType, dataRank, dataDimensions, NX_COMP_LZW, dataDimensions) != NX_OK) return NX_ERROR; if (NXopendata(outId, name) != NX_OK) return NX_ERROR; if (WriteAttributes(is_definition) != NX_OK) return NX_ERROR; if (NXputdata(outId, dataBuffer) != NX_OK) return NX_ERROR; if (NXfree(&dataBuffer) != NX_OK) return NX_ERROR; if (NXclosedata(outId) != NX_OK) return NX_ERROR; } remove_path(name); } else { // Make a link remove_path(name); strcpy(links_to_make[links_count].from, current_path); strcpy(links_to_make[links_count].to, link.targetPath); strcpy(links_to_make[links_count].name, name); links_count++; } if (NXclosedata(inId) != NX_OK) return NX_ERROR; } } else if (status == NX_EOD) { if (NXclosegroup(inId) != NX_OK) return NX_ERROR; if (NXclosegroup(outId) != NX_OK) return NX_ERROR; return NX_OK; } } while (status == NX_OK); return NX_OK; }
/** Write the group labeled "data" * * @param bank :: name of the bank * @param is_definition * @return error code */ int SaveToSNSHistogramNexus::WriteDataGroup(std::string bank, int is_definition) { int dataType, dataRank, dataDimensions[NX_MAXRANK]; NXname name; void *dataBuffer; if (NXgetinfo(inId, &dataRank, dataDimensions, &dataType) != NX_OK) return NX_ERROR; // Get the rectangular detector IComponent_const_sptr det_comp = inputWorkspace->getInstrument()->getComponentByName(std::string(bank)); RectangularDetector_const_sptr det = boost::dynamic_pointer_cast<const RectangularDetector>(det_comp); if (!det) { g_log.information() << "Detector '" + bank + "' not found, or it is not a rectangular detector!\n"; // Just copy that then. if (NXmalloc(&dataBuffer, dataRank, dataDimensions, dataType) != NX_OK) return NX_ERROR; if (NXgetdata(inId, dataBuffer) != NX_OK) return NX_ERROR; if (NXcompmakedata(outId, name, dataType, dataRank, dataDimensions, NX_COMP_LZW, dataDimensions) != NX_OK) return NX_ERROR; if (NXopendata(outId, name) != NX_OK) return NX_ERROR; if (WriteAttributes(is_definition) != NX_OK) return NX_ERROR; if (NXputdata(outId, dataBuffer) != NX_OK) return NX_ERROR; if (NXfree(&dataBuffer) != NX_OK) return NX_ERROR; if (NXclosedata(outId) != NX_OK) return NX_ERROR; } else { // YES it is a rectangular detector. // --- Memory requirements ---- size_t memory_required = size_t(det->xpixels() * det->ypixels()) * size_t(inputWorkspace->blocksize()) * 2 * sizeof(float); Kernel::MemoryStats mem; mem.update(); size_t memory_available = mem.availMem() * 1024; std::cout << "Memory available: " << memory_available / 1024 << " kb. "; std::cout << "Memory required: " << memory_required / 1024 << " kb. "; // Give a 50% margin of error in allocating the memory memory_available = memory_available / 2; if (memory_available > static_cast<size_t>(5e9)) memory_available = static_cast<size_t>(5e9); if (memory_available < memory_required) { // Compute how large of a slab you can still use. int x_slab; x_slab = static_cast<int>( memory_available / (det->ypixels() * inputWorkspace->blocksize() * 2 * sizeof(float))); if (x_slab <= 0) x_slab = 1; // Look for a slab size that evenly divides the # of pixels. while (x_slab > 1) { if ((det->xpixels() % x_slab) == 0) break; x_slab--; } std::cout << "Saving in slabs of " << x_slab << " X pixels.\n"; if (this->WriteOutDataOrErrors(det, x_slab, "data", "data_errors", false, false, is_definition, bank) != NX_OK) return NX_ERROR; if (this->WriteOutDataOrErrors(det, x_slab, "errors", "", true, false, is_definition, bank) != NX_OK) return NX_ERROR; } else { std::cout << "Saving in one block.\n"; if (this->WriteOutDataOrErrors(det, det->xpixels(), "data", "data_errors", false, true, is_definition, bank) != NX_OK) return NX_ERROR; } } return NX_OK; }
/** Utility function to write out the * data or errors to a field in the group. * * @param det :: rectangular detector being written * @param x_pixel_slab :: size of a slab to write, in number of X pixels. *ignored if doBoth * @param field_name :: "data" field name * @param errors_field_name :: "errors" field name. * @param doErrors :: set true if you are writing the errors field this time. *field_name should be the "errors" field name * @param doBoth :: do both data and errors at once, no slabbing. * @param is_definition :: * @param bank :: name of the bank being written. * @return error code */ int SaveToSNSHistogramNexus::WriteOutDataOrErrors( Geometry::RectangularDetector_const_sptr det, int x_pixel_slab, const char *field_name, const char *errors_field_name, bool doErrors, bool doBoth, int is_definition, std::string bank) { int dataRank, dataDimensions[NX_MAXRANK]; int slabDimensions[NX_MAXRANK], slabStartIndices[NX_MAXRANK]; dataRank = 3; // Dimension 0 = the X pixels dataDimensions[0] = det->xpixels(); // Dimension 1 = the Y pixels dataDimensions[1] = det->ypixels(); // Dimension 2 = time of flight bins dataDimensions[2] = static_cast<int>(inputWorkspace->blocksize()); // ---- Determine slab size ----- // Number of pixels to collect in X before slabbing slabDimensions[0] = x_pixel_slab; slabDimensions[1] = dataDimensions[1]; slabDimensions[2] = dataDimensions[2]; if (doBoth) slabDimensions[0] = dataDimensions[0]; std::cout << "RectangularDetector " << det->getName() << " being copied. Dimensions : " << dataDimensions[0] << ", " << dataDimensions[1] << ", " << dataDimensions[2] << ".\n"; // ----- Open the data field ----------------------- if (m_compress) { if (NXcompmakedata(outId, field_name, NX_FLOAT32, dataRank, dataDimensions, NX_COMP_LZW, slabDimensions) != NX_OK) return NX_ERROR; } else { if (NXmakedata(outId, field_name, NX_FLOAT32, dataRank, dataDimensions) != NX_OK) return NX_ERROR; } if (NXopendata(outId, field_name) != NX_OK) return NX_ERROR; if (WriteAttributes(is_definition) != NX_OK) return NX_ERROR; if (!doErrors) { // Add an attribute called "errors" with value = the name of the data_errors // field. NXname attrName = "errors"; std::string attrBuffer = errors_field_name; if (NXputattr(outId, attrName, attrBuffer.c_str(), static_cast<int>(attrBuffer.size()), NX_CHAR) != NX_OK) return NX_ERROR; } // ---- Errors field ----- if (doBoth) { if (NXclosedata(outId) != NX_OK) return NX_ERROR; if (m_compress) { if (NXcompmakedata(outId, errors_field_name, NX_FLOAT32, dataRank, dataDimensions, NX_COMP_LZW, slabDimensions) != NX_OK) return NX_ERROR; } else { if (NXmakedata(outId, errors_field_name, NX_FLOAT32, dataRank, dataDimensions) != NX_OK) return NX_ERROR; } if (NXopendata(outId, errors_field_name) != NX_OK) return NX_ERROR; // NXlink * link = new NXlink; // link->linkType = 1; /* SDS data link */ // NXgetdataID(outId, link); // std::string targetPath = "/entry/" + bank + "/" + errors_field_name; // strcpy(link->targetPath, targetPath.c_str()); // if (NXmakelink(outId,link) != NX_OK) // g_log.debug() << "Error while making link to " << targetPath << // '\n'; if (WriteAttributes(is_definition) != NX_OK) return NX_ERROR; if (NXclosedata(outId) != NX_OK) return NX_ERROR; } double fillTime = 0; double saveTime = 0; // Make a buffer of floats will all the counts in that bank. auto data = new float[slabDimensions[0] * slabDimensions[1] * slabDimensions[2]]; // Only allocate an array for errors if it is needed float *errors = nullptr; if (doBoth) errors = new float[slabDimensions[0] * slabDimensions[1] * slabDimensions[2]]; for (int x = 0; x < det->xpixels(); x++) { // Which slab are we in? int slabnum = x / x_pixel_slab; // X index into the slabbed output array int slabx = x % x_pixel_slab; Timer tim1; int ypixels = static_cast<int>(det->ypixels()); PARALLEL_FOR1(inputWorkspace) for (int y = 0; y < ypixels; y++) { PARALLEL_START_INTERUPT_REGION // Get the workspace index for the detector ID at this spot size_t wi = 0; try { wi = map.find(det->getAtXY(x, y)->getID())->second; } catch (...) { std::cout << "Error finding " << bank << " x " << x << " y " << y << "\n"; } // Offset into array. size_t index = size_t(slabx) * size_t(dataDimensions[1]) * size_t(dataDimensions[2]) + size_t(y) * size_t(dataDimensions[2]); const MantidVec &Y = inputWorkspace->readY(wi); const MantidVec &E = inputWorkspace->readE(wi); for (size_t i = 0; i < Y.size(); ++i) { if (doErrors) { data[i + index] = static_cast<float>(E[i]); } else { data[i + index] = static_cast<float>(Y[i]); if (doBoth) { errors[i + index] = static_cast<float>(E[i]); } } } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION fillTime += tim1.elapsed(); // Is this the last pixel in the slab? if (!doBoth && (x % x_pixel_slab == x_pixel_slab - 1)) { Timer tim2; // std::cout << "starting slab " << x << "\n"; // This is where the slab is in the greater data array. slabStartIndices[0] = slabnum * x_pixel_slab; slabStartIndices[1] = 0; slabStartIndices[2] = 0; if (NXputslab(outId, data, slabStartIndices, slabDimensions) != NX_OK) return NX_ERROR; saveTime += tim2.elapsed(); std::ostringstream mess; mess << det->getName() << ", " << field_name << " slab " << slabnum << " of " << det->xpixels() / x_pixel_slab; this->prog->reportIncrement(x_pixel_slab * det->ypixels(), mess.str()); } } // X loop if (doBoth) { bool returnerror = false; Timer tim2; if (NXopendata(outId, field_name) != NX_OK) returnerror = true; else if (NXputdata(outId, data) != NX_OK) returnerror = true; else if (NXclosedata(outId) != NX_OK) returnerror = true; else { this->prog->reportIncrement(det->xpixels() * det->ypixels() * 1, det->getName() + " data"); if (NXopendata(outId, errors_field_name) != NX_OK) returnerror = true; else if (NXputdata(outId, errors) != NX_OK) returnerror = true; else if (NXclosedata(outId) != NX_OK) returnerror = true; else { this->prog->reportIncrement(det->xpixels() * det->ypixels() * 1, det->getName() + " errors"); saveTime += tim2.elapsed(); } } if (returnerror) { delete[] data; delete[] errors; return NX_ERROR; } } else { if (NXclosedata(outId) != NX_OK) { delete[] data; return NX_ERROR; } } std::cout << "Filling out " << det->getName() << " took " << fillTime << " sec.\n"; std::cout << "Saving " << det->getName() << " took " << saveTime << " sec.\n"; delete[] data; if (doBoth) delete[] errors; return NX_OK; }