Exemple #1
0
  int NexusFileIO::getXValues(MantidVec& xValues, const int& spectra) const
  {
    //
    // find the X values for spectra. If uniform, the spectra number is ignored.
    //
   int rank,dim[2],type;

    //open workspace group
    NXstatus status=NXopengroup(fileID,"workspace","NXdata");
    if(status==NX_ERROR)
      return(1);
    // read axis1 size
    status=NXopendata(fileID,"axis1");
    if(status==NX_ERROR)
      return(2);
    NXgetinfo(fileID, &rank, dim, &type);
    if(rank==1)
    {
      NXgetdata(fileID,&xValues[0]);
    }
    else
    {
      int start[2]={spectra,0};
      int  size[2]={1,dim[1]};
      NXgetslab(fileID,&xValues[0],start,size);
    }
    NXclosedata(fileID);
    NXclosegroup(fileID);
    return(0);
  }
Exemple #2
0
/*------------------------------------------------------------------------*/
void *nx_getdata(void *handle){
  pNXDS result = NULL;
  int rank, type,dim[NX_MAXRANK],status;
  NXhandle hfil;


  hfil = (NXhandle)handle;
  status = NXgetinfo(hfil,&rank,dim,&type);
  if(status != NX_OK){
    return NULL;
  }

  result = createNXDataset32(rank,type,dim);
  if(result == NULL){
    NXclosedata(hfil);
    return NULL;
  }

  status = NXgetdata(hfil,result->u.ptr);
  if(result == NULL){
    dropNXDataset(result);
    return NULL;
  }
  return result;
}
Exemple #3
0
/* Dumps requested data */
int NXBdump(NXhandle fileId, NXname dataName, char *fileName)
{
    int dataRank, dataDimensions[NX_MAXRANK], dataType, i;
    FILE *fd = NULL;
    void *dataBuffer;

    /* Check the specified data item exists */
    if (FindData(fileId, dataName) != NX_OK)
        return NX_ERROR;

    /* Open the data and obtain its type and rank details */
    if (NXopendata(fileId, dataName) != NX_OK)
        return NX_ERROR;
    if (NXgetinfo(fileId, &dataRank, dataDimensions, &dataType) != NX_OK)
        return NX_ERROR;

    /* Open the file */
    fd = fopen(fileName, "w");
    if (!fd) {
        printf("ERROR: failed to open--> %s <-- for writing\n",
               fileName);
        return NX_ERROR;
    }

    /* Allocate data space */
    if (NXmalloc(&dataBuffer, dataRank, dataDimensions, dataType) != NX_OK)
        return NX_ERROR;

    /* Read the lot */
    if (NXgetdata(fileId, dataBuffer) != NX_OK)
        return NX_ERROR;

    if (NXclosedata(fileId) != NX_OK)
        return NX_ERROR;

    /* Print a header */
    fprintf(fd, "File : %s, DataSet: %s \n", nxFile, dataName);
    for (i = 0; i < dataRank; i++) {
        fprintf(fd, " %d ", dataDimensions[i]);
    }
    fprintf(fd, "\n");

    /* Dump the data */
    DumpData(fd, dataRank, dataDimensions, dataType, dataBuffer);

    /* Clean up */
    fclose(fd);
    NXfree(&dataBuffer);
    return NX_OK;
}
Exemple #4
0
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;
}
Exemple #5
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;
}
/*------------------------------------------------------------------------*/
static pNEventArray loadAMOR(char *filename)
{
    NXhandle handle;
    int32_t dim[3];
    int status, i, j, k, l, nCount, rank, type;
    unsigned int size, offset;
    int32_t *data = NULL;
    float *tof = NULL;
    int32_t iTof;
    unsigned long nEvents;
    pNEventArray evData = NULL;
    unsigned int detID = -1;

    status = NXopen(filename,NXACC_READ,&handle);
    if(status != NX_OK) {
        printf("Failed to open NeXus file %s\n", filename);
        return NULL;
    }

    status = NXopenpath(handle,"/entry1/AMOR/area_detector/data");
    if(status != NX_OK) {
        printf("NeXus file %s in wrong format\n", filename);
        return NULL;
    }
    NXgetinfo(handle,&rank,dim,&type);
    for(i = 1, size = dim[0]; i < 3; i++) {
        size *= dim[i];
    }
    data = malloc(size*sizeof(int32_t));
    tof = malloc(dim[2]*sizeof(float));
    if(data == NULL || tof == NULL ) {
        printf("failed to allocate memory for NeXus data\n");
        return NULL;
    }
    NXgetdata(handle,data);

    status = NXopenpath(handle,"/entry1/AMOR/area_detector/time_binning");
    if(status != NX_OK) {
        printf("NeXus file %s in wrong format\n", filename);
        return NULL;
    }
    NXgetdata(handle,tof);

    NXclose(&handle);

    nEvents = countNeutrons(data,size);
    evData = createNEventArray(nEvents);
    if(evData == NULL) {
        return NULL;
    }
    printf("%s contains %ld neutrons\n",filename,nEvents);

    nEvents = 0;
    for(i = 0; i < dim[0]; i++) {
        for(j = 0; j < dim[1]; j++) {
            detID++;
            offset = i*dim[1]*dim[2] + j*dim[2];
            for(k = 0; k < dim[2]; k++) {
                nCount = data[offset+k];
                iTof = round(tof[k]/10.);
                for(l = 0; l < nCount; l++) {
                    evData->detectorID[nEvents] = detID;
                    evData->timeStamp[nEvents] = iTof;
                    nEvents++;
                }
            }
        }
    }

    return evData;
}
Exemple #7
0
/* Outputs requested data */
int NXBread(NXhandle fileId, NXname dataName, char *dimensions)
{
    int dataRank, dataDimensions[NX_MAXRANK], dataType, start[NX_MAXRANK],
        size[NX_MAXRANK], i, j, total_size;
    char dimString[80], *subString;
    void *dataBuffer;

    /* Check the specified data item exists */
    if (FindData(fileId, dataName) != NX_OK)
        return NX_ERROR;
    /* Open the data and obtain its type and rank details */
    if (NXopendata(fileId, dataName) != NX_OK)
        return NX_ERROR;
    if (NXgetinfo(fileId, &dataRank, dataDimensions, &dataType) != NX_OK)
        return NX_ERROR;
    /* Check if a single element has been specified */
    /* If so, read in the indices */
    if (dimensions != NULL) {
        strcpy(dimString, dimensions);
        subString = strtok(dimString, ",");
        for (i = 0; subString != NULL && i < NX_MAXRANK; i++) {
            if (i >= dataRank) {
                printf("NX_ERROR: Data rank = %d\n", dataRank);
                return NX_ERROR;
            }
            sscanf(subString, "%d", &j);
            if (j > dataDimensions[i] || j < 1) {
                printf("NX_ERROR: Data dimension %d = %d\n",
                       (i + 1), dataDimensions[i]);
                return NX_ERROR;
            }
            start[i] = j - 1;
            size[i] = 1;
            subString = strtok(NULL, ",");
        }
        if (i != dataRank) {
            printf("NX_ERROR: Data rank = %d\n", dataRank);
            return NX_ERROR;
        }
    } else {
        /* Otherwise, allocate enough space for the first 3 elements of each dimension */
        for (i = 0; i < dataRank; i++) {
            if (dataDimensions[i] > 3 && dataType != NX_CHAR) {
                start[i] = 0;
                size[i] = 3;
            } /* unless it's a character string */
            else {
                start[i] = 0;
                size[i] = dataDimensions[i];
            }
        }
    }
    total_size = 1;
    for (i = 0; i < dataRank; i++) {
        total_size *= dataDimensions[i];
    }
    if (NXmalloc((void **)&dataBuffer, dataRank, size, dataType) != NX_OK)
        return NX_ERROR;
    /* Read in the data with NXgetslab */
    if (dataType == NX_CHAR) {
        if (NXgetdata(fileId, dataBuffer) != NX_OK)
            return NX_ERROR;
    } else {
        if (NXgetslab(fileId, dataBuffer, start, size) != NX_OK)
            return NX_ERROR;
    }
    /* Output data name, dimensions and type */
    printf("  %s", dataName);
    if (dimensions == NULL)
        PrintDimensions(dataRank, dataDimensions);
    else
        printf("[%s]", dimensions);
    printf(" ");
    PrintType(dataType);
    printf(" = ");
    /* Output the data according to data type */
    if (dimensions == NULL) {	/* Print the first few values (max 3) */
        if (dataType == NX_CHAR) {	/* If the data is a string, output the whole buffer */
            /* this prints the first line of an array; could print more */
            for (i = 0;
                    i < total_size / dataDimensions[dataRank - 1];
                    i++) {
                PrintData((char *)dataBuffer +
                          i * dataDimensions[dataRank - 1],
                          dataType,
                          dataDimensions[dataRank - 1]);
                PrintData("\n", NX_CHAR, 1);
            }
        } else {
            if (dataRank == 1 && dataDimensions[0] == 1) {	/* It's a scalar */
                PrintData(dataBuffer, dataType, 1);
            } else {	/* It's an array */
                printf("[ ");
                /* Determine total size of input buffer */
                for (i = 0, j = 0; i < dataRank; i++)
                    j += dataDimensions[i];
                /* Output at least 3 values */
                if (j > 3) {
                    PrintData(dataBuffer, dataType, 3);
                    printf("...");
                }
                /* unless the total size is smaller */
                else {
                    PrintData(dataBuffer, dataType, j);
                }
                printf("]");
            }
        }
    } else {		/* Print the requested item */
        PrintData(dataBuffer, dataType, 1);
    }
    printf("\n");
    if (NXfree((void **)&dataBuffer) != NX_OK)
        return NX_ERROR;

    /* Check for attributes unless a single element is specified */
    if (dimensions == NULL)
        PrintAttributes(fileId);

    /* Close data set */
    if (NXclosedata(fileId) != NX_OK)
        return NX_ERROR;

    return NX_OK;
}
Exemple #8
0
    /**
     * Recursively add properties from a nexus file to
     * the workspace run.
     *
     * @param nxfileID    :: Nexus file handle to be parsed, just after an NXopengroup
     * @param runDetails  :: where to add properties
     * @param parent_name :: nexus caller name
     * @param parent_class :: nexus caller class
     * @param level       :: current level in nexus tree
     *
     */
    void LoadHelper::recurseAndAddNexusFieldsToWsRun(NXhandle nxfileID, API::Run& runDetails,
        std::string& parent_name, std::string& parent_class, int level)
    {

      std::string indent_str(level * 2, ' '); // Two space by indent level

      // Link ?

      // Attributes ?

      // Classes
      NXstatus getnextentry_status;       ///< return status
      int datatype; ///< NX data type if a dataset, e.g. NX_CHAR, NX_FLOAT32, see napi.h
      char nxname[NX_MAXNAMELEN], nxclass[NX_MAXNAMELEN];
      nxname[0] = '0';
      nxclass[0] = '0';

      bool has_entry = true; // follows getnextentry_status
      while (has_entry)
      {
        getnextentry_status = NXgetnextentry(nxfileID, nxname, nxclass, &datatype);

        if (getnextentry_status == NX_OK)
        {
          g_log.debug() << indent_str << parent_name << "." << nxname << " ; " << nxclass << std::endl;

          NXstatus opengroup_status;
          NXstatus opendata_status;

          if ((opengroup_status = NXopengroup(nxfileID, nxname, nxclass)) == NX_OK)
          {

            // Go down to one level
            std::string p_nxname(nxname); //current names can be useful for next level
            std::string p_nxclass(nxclass);

            recurseAndAddNexusFieldsToWsRun(nxfileID, runDetails, p_nxname, p_nxclass, level + 1);

            NXclosegroup(nxfileID);
          }        // if(NXopengroup
          else if ((opendata_status = NXopendata(nxfileID, nxname)) == NX_OK)
          {
            //dump_attributes(nxfileID, indent_str);
            g_log.debug() << indent_str << nxname << " opened." << std::endl;

            if (parent_class == "NXData" || parent_class == "NXMonitor" || std::string(nxname) == "data")
            {
              g_log.debug() << indent_str << "skipping " << parent_class << " (" << nxname << ")"
                  << std::endl;
              /* nothing */
            }
            else
            { // create a property
              int rank;
              int dims[4];
              int type;
              dims[0] = dims[1] = dims[2] = dims[3] = 0;

              std::string property_name = (parent_name.empty() ? nxname : parent_name + "." + nxname);

              g_log.debug() << indent_str << "considering property " << property_name << std::endl;

              // Get the value
              NXgetinfo(nxfileID, &rank, dims, &type);

              // Note, we choose to only build properties on small float arrays
              // filter logic is below
              bool build_small_float_array = false;              // default

              if ((type == NX_FLOAT32) || (type == NX_FLOAT64))
              {
                if ((rank == 1) && (dims[0] <= 9))
                {
                  build_small_float_array = true;
                }
                else
                {
                  g_log.debug() << indent_str << "ignored multi dimension float data on "
                      << property_name << std::endl;
                }
              }
              else if (type != NX_CHAR)
              {
                if ((rank != 1) || (dims[0] != 1) || (dims[1] != 1) || (dims[2] != 1) || (dims[3] != 1))
                {
                  g_log.debug() << indent_str << "ignored multi dimension data on " << property_name
                      << std::endl;
                }
              }

              void *dataBuffer;
              NXmalloc(&dataBuffer, rank, dims, type);

              if (NXgetdata(nxfileID, dataBuffer) != NX_OK)
              {
                NXfree(&dataBuffer);
                throw std::runtime_error("Cannot read data from NeXus file");
              }

              if (type == NX_CHAR)
              {
                std::string property_value((const char *) dataBuffer);
                if (boost::algorithm::ends_with(property_name, "_time"))
                {
                  // That's a time value! Convert to Mantid standard
                  property_value = dateTimeInIsoFormat(property_value);
                }
                runDetails.addProperty(property_name, property_value);

              }
              else if ((type == NX_FLOAT32) || (type == NX_FLOAT64) || (type == NX_INT16)
                  || (type == NX_INT32) || (type == NX_UINT16))
              {

                // Look for "units"
                NXstatus units_status;
                char units_sbuf[NX_MAXNAMELEN];
                int units_len = NX_MAXNAMELEN;
                int units_type = NX_CHAR;

                units_status = NXgetattr(nxfileID, const_cast<char*>("units"), (void *) units_sbuf,
                    &units_len, &units_type);
                if (units_status != NX_ERROR)
                {
                  g_log.debug() << indent_str << "[ " << property_name << " has unit " << units_sbuf
                      << " ]" << std::endl;
                }

                if ((type == NX_FLOAT32) || (type == NX_FLOAT64))
                {
                  // Mantid numerical properties are double only.
                  double property_double_value = 0.0;

                  // Simple case, one value
                  if (dims[0] == 1)
                  {
                    if (type == NX_FLOAT32)
                    {
                      property_double_value = *((float*) dataBuffer);
                    }
                    else if (type == NX_FLOAT64)
                    {
                      property_double_value = *((double*) dataBuffer);
                    }
                    if (units_status != NX_ERROR)
                      runDetails.addProperty(property_name, property_double_value,
                          std::string(units_sbuf));
                    else
                      runDetails.addProperty(property_name, property_double_value);
                  }
                  else if (build_small_float_array)
                  {
                    // An array, converted to "name_index", with index < 10 (see test above)
                    for (int dim_index = 0; dim_index < dims[0]; dim_index++)
                    {
                      if (type == NX_FLOAT32)
                      {
                        property_double_value = ((float*) dataBuffer)[dim_index];
                      }
                      else if (type == NX_FLOAT64)
                      {
                        property_double_value = ((double*) dataBuffer)[dim_index];
                      }
                      std::string indexed_property_name = property_name + std::string("_")
                          + boost::lexical_cast<std::string>(dim_index);
                      if (units_status != NX_ERROR)
                        runDetails.addProperty(indexed_property_name, property_double_value,
                            std::string(units_sbuf));
                      else
                        runDetails.addProperty(indexed_property_name, property_double_value);
                    }
                  }

                }
                else
                {
                  // int case
                  int property_int_value = 0;
                  if (type == NX_INT16)
                  {
                    property_int_value = *((short int*) dataBuffer);
                  }
                  else if (type == NX_INT32)
                  {
                    property_int_value = *((int*) dataBuffer);
                  }
                  else if (type == NX_UINT16)
                  {
                    property_int_value = *((short unsigned int*) dataBuffer);
                  }

                  if (units_status != NX_ERROR)
                    runDetails.addProperty(property_name, property_int_value, std::string(units_sbuf));
                  else
                    runDetails.addProperty(property_name, property_int_value);

                } // if (type==...

              }
              else
              {
                g_log.debug() << indent_str << "unexpected data on " << property_name << std::endl;
              } // test on nxdata type

              NXfree(&dataBuffer);
              dataBuffer = NULL;

            } // if (parent_class == "NXData" || parent_class == "NXMonitor") else

            NXclosedata(nxfileID);
          }
          else
          {
            g_log.debug() << indent_str << "unexpected status (" << opendata_status << ") on " << nxname
                << std::endl;
          }

        }
        else if (getnextentry_status == NX_EOD)
        {
          g_log.debug() << indent_str << "End of Dir" << std::endl;
          has_entry = false; // end of loop
        }
        else
        {
          g_log.debug() << indent_str << "unexpected status (" << getnextentry_status << ")"
              << std::endl;
          has_entry = false; // end of loop
        }

      } // while

    } // recurseAndAddNexusFieldsToWsRun
Exemple #9
0
 /** Get all the Nexus entry types for a file
  *
  * Try to open named Nexus file and return all entries plus the definition found for each.
  * If definition not found, try and return "analysis" field (Muon V1 files)
  * Closes file on exit.
  *
  * @param fileName :: file to open
  * @param entryName :: vector that gets filled with strings with entry names
  * @param definition :: vector that gets filled with the "definition" or "analysis" string.
  * @return count of entries if OK, -1 failed to open file.
  */
 int getNexusEntryTypes(const std::string& fileName, std::vector<std::string>& entryName,
     std::vector<std::string>& definition )
 {
   //
   //
   NXhandle fileH;
   NXaccess mode= NXACC_READ;
   NXstatus stat=NXopen(fileName.c_str(), mode, &fileH);
   if(stat==NX_ERROR) return(-1);
   //
   entryName.clear();
   definition.clear();
   char *nxname,*nxclass;
   int nxdatatype;
   nxname= new char[NX_MAXNAMELEN];
   nxclass = new char[NX_MAXNAMELEN];
   int rank,dims[2],type;
   //
   // Loop through all entries looking for the definition section in each (or analysis for MuonV1)
   //
   std::vector<std::string> entryList;
   while( ( stat=NXgetnextentry(fileH,nxname,nxclass,&nxdatatype) ) == NX_OK )
   {
     std::string nxc(nxclass);
     if(nxc.compare("NXentry")==0)
       entryList.push_back(nxname);
   }
   // for each entry found, look for "analysis" or "definition" text data fields and return value plus entry name
   for(size_t i=0;i<entryList.size();i++)
   {
     //
     stat=NXopengroup(fileH,entryList[i].c_str(),"NXentry");
     // loop through field names in this entry
     while( ( stat=NXgetnextentry(fileH,nxname,nxclass,&nxdatatype) ) == NX_OK )
     {
       std::string nxc(nxclass),nxn(nxname);
       // if a data field
       if(nxc.compare("SDS")==0)
         // if one of the two names we are looking for
         if(nxn.compare("definition")==0 || nxn.compare("analysis")==0)
         {
           NXopendata(fileH,nxname);
           stat=NXgetinfo(fileH,&rank,dims,&type);
           if(stat==NX_ERROR)
             continue;
           char* value=new char[dims[0]+1];
           stat=NXgetdata(fileH,value);
           if(stat==NX_ERROR)
             continue;
           value[dims[0]]='\0';
           // return e.g entryName "analysis"/definition "muonTD"
           definition.push_back(value);
           entryName.push_back(entryList[i]);
           delete[] value;
           NXclosegroup(fileH); // close data group, then entry
           stat=NXclosegroup(fileH);
           break;
         }
     }
   }
   stat=NXclose(&fileH);
   delete[] nxname;
   delete[] nxclass;
   return(static_cast<int>(entryName.size()));
 }
/** 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;
}