ICP  1
nexuswriter.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 #include "isiscrpt.h"
3 #include "isisraw.h"
4 #include "nexuswriter.h"
5 #include "icputils.h"
6 #include "selogger.h"
7 #include "NeXusEventWriter.h"
8 
9 
10 #define MIN_COMP_LEN 25
11 static int* makeNewRawData(const isisU32_t* raw_data, int nper_daq,
13  int nsp1, int ntc1)
14 {
15  int i, j, k;
16  int* new_raw_data = new int[nsp1*nper_daq*ntc1];
17  for(k=0; k<nper_daq; k++)
18  {
19  for(j=0; j<nsp1; j++)
20  {
21  for(i=0; i<ntc1; i++)
22  {
23  new_raw_data[i + j*ntc1 + k*ntc1*nsp1] =
24  raw_data[(i+1) + (j+1)*(ntc1+1) + k*(nsp1+1)*(ntc1+1)];
25  }
26  }
27  }
28  return new_raw_data;
29 }
30 
31 
32 static char* remove_invalid_chars(const char* str, int len)
33 {
34  int i;
35  const unsigned char* ustr = (const unsigned char*)str;
36  unsigned char* res = new unsigned char[len+1];
37  for(i=0; i<len; i++)
38  {
39  if ( (ustr[i] == '\0') || (ustr[i] > 127) || !isprint(ustr[i]) )
40  {
41  res[i] = '?'; // use '?' rather than ' ' to preserve string length when read with whitespace stripping
42  }
43  else
44  {
45  res[i] = ustr[i];
46  }
47  }
48  res[len] = '\0';
49  return (char*)res;
50 }
51 
52 template<typename T>
53  static const T* nullValue(const T* /*value*/, int NXTYPE)
54  {
55  static const int izero = 0;
56  static const int izero64 = 0;
57  static const float fzero = 0.0;
58  static const double dzero = 0.0;
59  switch(NXTYPE)
60  {
61  case NX_INT32:
62  case NX_UINT32:
63  return (T*)&izero;
64  case NX_INT64:
65  case NX_UINT64:
66  return (T*)&izero64;
67  case NX_FLOAT32:
68  return (T*)&fzero;
69  case NX_FLOAT64:
70  return (T*)&dzero;
71  case NX_CHAR:
72  return (T*)" ";
73  default:
74  return NULL;
75  }
76  }
77 
78 template<typename T, int NXTYPE>
79  static int writeAttribute(NXhandle fileid, const char* data_name,
80  const char* attr_name, const T* value, int len, bool convert_null)
81  {
82  if (len == 0)
83  {
84  if (convert_null)
85  {
86  value = nullValue(value, NXTYPE);
87  len = 1;
88  }
89  else
90  {
91  return 0;
92  }
93  }
94  if (NXopendata(fileid, data_name) == NX_OK)
95  {
96  NXputattr(fileid, attr_name, (void*)value, len, NXTYPE);
97  NXclosedata(fileid);
98  }
99  return 0;
100  }
101 
102 template<typename T, int NXTYPE>
103  static int writeAttribute(NXhandle fileid, const char* data_name,
104  const char* attr_name, T value, bool convert_null)
105  {
106  return writeAttribute<T,NXTYPE>(fileid, data_name, attr_name, &value, 1, convert_null);
107  }
108 
109 template<typename T, int NXTYPE>
110  static int writeData(NXhandle fileid, const char* data_name,
111  const T* value, const int* dims_array, int ndims, bool convert_null, int compression_type)
112  {
113  NXstatus ret;
114  int i, len = 1;
115  int dummy_dims_array[1] = { 1 };
116  int* chunk_size = new int[ndims];
117  for(i=0; i<ndims; i++)
118  {
119  len *= dims_array[i];
120  }
121  if (len == 0)
122  {
123  if (convert_null || value != NULL)
124  {
125  value = nullValue(value, NXTYPE);
126  ndims = 1;
127  dims_array = dummy_dims_array;
128  }
129  else
130  {
131  ret = NXmakedata(fileid, data_name, NXTYPE, ndims, (int*)dims_array); // create an empty zero size array with no data
132  delete []chunk_size;
133  return 0;
134  }
135  }
136  // we want only the final array dimension to be compressed
137  for(i=0; i<ndims; i++)
138  {
139  chunk_size[i] = 1;
140  }
141  chunk_size[ndims-1] = dims_array[ndims-1];
142  if ( (compression_type != NX_COMP_NONE) && (chunk_size[ndims-1] > MIN_COMP_LEN) )
143  {
144  ret = NXcompmakedata(fileid, data_name, NXTYPE, ndims, (int*)dims_array, compression_type, chunk_size);
145  }
146  else
147  {
148  ret = NXmakedata(fileid, data_name, NXTYPE, ndims, (int*)dims_array);
149  }
150  delete []chunk_size;
151  if (ret != NX_OK)
152  {
153  return 0;
154  }
155  NXopendata(fileid, data_name);
156  NXputdata(fileid, (void*)value);
157  NXclosedata(fileid);
158  return 0;
159  }
160 
161 
162 
163 // we want to write a portion of an array to the file
164 // the passed array is of size (dims_array[ndims]) but we only
165 // want to write a slab of it
166 // only for ndims = 1 or 2 at moment
167 template<typename T, int NXTYPE>
168  static int addSlab(NXhandle fileid,
169  const T* value, const int64_t* dims_array, int ndims,
170  const int64_t* slab_start, const int64_t* slab_size,
171  const int64_t* dest_start, int compression_type)
172  {
173 // const int BUFFER_SIZE = 1024 * 1024;
174  int64_t i, j, offset;
175  int64_t dims[10], sizes[10];
176  if (ndims == 1)
177  {
178  NXputslab64(fileid, (void*)(value+slab_start[0]), (int64_t*)dest_start, (int64_t*)slab_size);
179  }
180  else if (ndims == 2)
181  {
182  dims[1] = dest_start[1]; sizes[0] = 1; sizes[1] = slab_size[1];
183  for(i=0; i<slab_size[0]; i++)
184  {
185  offset = (i + slab_start[0]) * dims_array[1] + slab_start[1];
186  dims[0] = i + dest_start[0];
187  NXputslab64(fileid, (void*)(value + offset), dims, sizes);
188  }
189  }
190  else if (ndims == 3)
191  {
192  dims[2] = dest_start[2]; sizes[0] = 1; sizes[1] = 1; sizes[2] = slab_size[2];
193  for(i=0; i<slab_size[0]; i++)
194  {
195  for(j=0; j<slab_size[1]; j++)
196  {
197  offset = (i + slab_start[0]) * (dims_array[1] * dims_array[2]) +
198  (j + slab_start[1]) * dims_array[2] +
199  slab_start[2];
200  dims[1] = j + dest_start[1];
201  dims[0] = i + dest_start[0];
202  NXputslab64(fileid, (void*)(value + offset), dims, sizes);
203  }
204  }
205  }
206  return 0;
207  }
208 
209 template<typename T, int NXTYPE>
210  static int addSlab(NXhandle fileid,
211  const T* value, const int* dims_array, int ndims,
212  const int* slab_start, const int* slab_size,
213  const int* dest_start, int compression_type)
214 {
215  std::vector<int64_t> t_dims_array(dims_array, dims_array+ndims);
216  std::vector<int64_t> t_slab_start(slab_start, slab_start+ndims);
217  std::vector<int64_t> t_slab_size(slab_size, slab_size+ndims);
218  std::vector<int64_t> t_dest_start(dest_start, dest_start+ndims);
219  return addSlab<T,NXTYPE>(fileid, value, &(t_dims_array[0]), ndims, &(t_slab_start[0]), &(t_slab_size[0]), &(t_dest_start[0]), compression_type);
220 }
221 
222 template<typename T, int NXTYPE>
223  static int addSlab(NXhandle fileid, const char* data_name,
224  const T* value, const int* dims_array, int ndims,
225  const int* slab_start, const int* slab_size,
226  const int* dest_start, int compression_type)
227 {
228  NXopendata(fileid, data_name);
229  addSlab<T,NXTYPE>(fileid, value, dims_array, ndims, slab_start, slab_size, dest_start, compression_type);
230  NXclosedata(fileid);
231  return 0;
232 }
233 
234 // we want to write a portion of an array to the file
235 // the passed array is of size (dims_array[ndims]) but we only
236 // want to write a slab of it
237 // only for ndims = 1 or 2 at moment
238 template<typename T, int NXTYPE>
239  static int writeSlab(NXhandle fileid, const char* data_name,
240  const T* value, const int* dims_array, int ndims,
241  const int* slab_start, const int* slab_size, bool convert_null, int compression_type)
242  {
243  const int BUFFER_SIZE = 1024 * 1024;
244  NXstatus ret;
245  int zero = 0;
246  int i, j, offset;
247  int dims[10], sizes[10];
248  int* chunk_size = new int[ndims];
249  // we want only the final array dimension to be compressed
250  for(i=0; i<ndims; i++)
251  {
252  chunk_size[i] = 1;
253  }
254  chunk_size[ndims-1] = slab_size[ndims-1];
255  if ( (compression_type != NX_COMP_NONE) && (chunk_size[ndims-1] > MIN_COMP_LEN) )
256  {
257  ret = NXcompmakedata(fileid, data_name, NXTYPE, ndims, (int*)slab_size, compression_type, chunk_size);
258  }
259  else
260  {
261  ret = NXmakedata(fileid, data_name, NXTYPE, ndims, (int*)slab_size);
262  }
263  delete[] chunk_size;
264  if (ret != NX_OK)
265  {
266  return 0;
267  }
268  NXopendata(fileid, data_name);
269  if (ndims == 1)
270  {
271  NXputslab(fileid, (void*)(value+slab_start[0]), &zero, (int*)slab_size);
272  }
273  else if (ndims == 2)
274  {
275  dims[1] = 0; sizes[0] = 1; sizes[1] = slab_size[1];
276  for(i=0; i<slab_size[0]; i++)
277  {
278  offset = (i + slab_start[0]) * dims_array[1] + slab_start[1];
279  dims[0] = i;
280  NXputslab(fileid, (void*)(value + offset), dims, sizes);
281  }
282  }
283  else if (ndims == 3)
284  {
285  dims[2] = 0; sizes[0] = 1; sizes[1] = 1; sizes[2] = slab_size[2];
286  for(i=0; i<slab_size[0]; i++)
287  {
288  for(j=0; j<slab_size[1]; j++)
289  {
290  offset = (i + slab_start[0]) * (dims_array[1] * dims_array[2]) +
291  (j + slab_start[1]) * dims_array[2] +
292  slab_start[2];
293  dims[1] = j;
294  dims[0] = i;
295  NXputslab(fileid, (void*)(value + offset), dims, sizes);
296  }
297  }
298  }
299  NXclosedata(fileid);
300  return 0;
301  }
302 
303 
304 
305 // we want to write a portion of an array to the file
306 // the passed array is of size (dims_array[ndims]) but we only
307 // want to write a slab of it
308 // only for ndims = 1 or 2 at moment
309 template<int NXTYPE>
310  static int makeDataSlab(NXhandle fileid, const char* data_name,
311  const int* dims_array, int ndims,
312  int compression_type, int spectra_chunk)
313  {
314  const int BUFFER_SIZE = 1024 * 1024;
315  NXstatus ret;
316  int zero = 0;
317 // int nxtype = NeXus::getType<T>();
318  int i;
319  int* chunk_size = new int[ndims];
320  // we want only the final array dimension to be compressed
321  for(i=0; i<ndims; i++)
322  {
323  chunk_size[i] = 1;
324  }
325  chunk_size[ndims-1] = dims_array[ndims-1];
326  if (ndims > 1)
327  {
328  if (dims_array[ndims-2] > spectra_chunk)
329  {
330  chunk_size[ndims-2] = spectra_chunk; // spectra_chunk spectra per block
331  }
332  else
333  {
334  chunk_size[ndims-2] = dims_array[ndims-2];
335  }
336  }
337  if ( (compression_type != NX_COMP_NONE) && (chunk_size[ndims-1] > MIN_COMP_LEN) )
338  {
339  ret = NXcompmakedata(fileid, data_name, NXTYPE, ndims, (int*)dims_array, compression_type, chunk_size);
340  }
341  else
342  {
343  ret = NXmakedata(fileid, data_name, NXTYPE, ndims, (int*)dims_array);
344  }
345  delete[] chunk_size;
346  if (ret != NX_OK)
347  {
348  return 0;
349  }
350  return 0;
351  }
352 
353 
354 
361 template<typename T, int NXTYPE>
362  static int addSlabList(NXhandle fileid, const char* data_name,
363  const T* value, const int* dims_array, int ndims, int dest_start[],
364  const int* slab_start, const int* slab_size, const std::vector<int>& slab_list,
365  bool convert_null, int compression_type, int spectra_chunk)
366  {
367  int zero = 0;
368  int i, j, offset;
369  int dims[10], sizes[10];
370  NXopendata(fileid, data_name);
371  if (ndims == 1)
372  {
373  NXputslab(fileid, (void*)(value+slab_start[0]), &(dest_start[0]), (int*)slab_size);
374  }
375  else if (ndims == 2)
376  {
377  dims[1] = dest_start[1]; sizes[0] = 1; sizes[1] = slab_size[1]; // slab_start[0] not used - use slab_list instead
378  for(i = 0; i < slab_list.size(); ++i)
379  {
380  offset = (slab_list[i]) * dims_array[1] + slab_start[1];
381  dims[0] = i + dest_start[0];
382  NXputslab(fileid, (void*)(value + offset), dims, sizes);
383  }
384  }
385  else if (ndims == 3)
386  {
387  dims[2] = dest_start[2]; sizes[0] = 1; sizes[1] = 1; sizes[2] = slab_size[2];
388  for(i=0; i<slab_size[0]; i++)
389  { // slab_start[1] not used - use slab_list instead
390  for(j=0; j < slab_list.size(); ++j)
391  {
392  offset = (i + slab_start[0]) * (dims_array[1] * dims_array[2]) +
393  (slab_list[j]) * dims_array[2] +
394  slab_start[2];
395  dims[1] = j + dest_start[1];
396  dims[0] = i + dest_start[0];
397  NXputslab(fileid, (void*)(value + offset), dims, sizes);
398  }
399  }
400  }
401  NXclosedata(fileid);
402  return 0;
403  }
404 
405 
406 // we want to write a portion of an array to the file
407 // the passed array is of size (dims_array[ndims]) but we only
408 // want to write a slab of it
409 // only for ndims = 1 or 2 at moment
410 template<typename T, int NXTYPE>
411  static int writeSlabList(NXhandle fileid, const char* data_name,
412  const T* value, const int* dims_array, int ndims,
413  const int* slab_start, const int* slab_size, const std::vector<int>& slab_list,
414  bool convert_null, int compression_type, int spectra_chunk)
415  {
416  int ret = makeDataSlab<NXTYPE>(fileid, data_name, slab_size, ndims, compression_type, spectra_chunk);
417  if (ret != 0)
418  {
419  return ret;
420  }
421  int start_index[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
422  ret = addSlabList<T,NXTYPE>(fileid, data_name, value, dims_array, ndims, start_index, slab_start,
423  slab_size, slab_list, convert_null, compression_type, spectra_chunk);
424  return ret;
425  }
426 
427 
428 template<typename T, int NXTYPE>
429  static int writeData(NXhandle fileid, const char* data_name, T value, bool convert_null, int compression_type)
430  {
431  int one(1);
432  return writeData<T,NXTYPE>(fileid, data_name, &value, &one, 1, convert_null, compression_type);
433  }
434 
435 template<typename T, int NXTYPE>
436  static int writeData(NXhandle fileid, const char* data_name, const T* value, int len, bool convert_null, int compression_type)
437  {
438  return writeData<T,NXTYPE>(fileid, data_name, value, &len, 1, convert_null, compression_type);
439  }
440 
441 template<typename T, int NXTYPE>
442  static int writeData(NXhandle fileid, const char* data_name, const T* value, int dim1, int dim2, bool convert_null, int compression_type)
443  {
444  int dims_array[2] = { dim1, dim2 };
445  return writeData<T,NXTYPE>(fileid, data_name, value, dims_array, 2, convert_null, compression_type);
446  }
447 
448 void IXNeXusFile::setErrorReporter(nx_error_t error_func, void* error_arg)
449 {
450  m_error_func = error_func;
451  m_error_arg = error_arg;
452  NXMSetError(error_arg, error_func);
453 }
454 
455 IXNeXusFile::IXNeXusFile(nx_error_t error_func, void* error_arg) : m_fileid(0), m_options(0), m_compression_type(NX_COMP_NONE),
456  m_spectra_chunk(8), m_error_func(NULL), m_error_arg(NULL)
457 {
458  setLoggerName("NeXusFile");
459  if (error_func != NULL)
460  {
461  setErrorReporter(error_func, error_arg);
462  }
463 }
464 
466 {
469  m_options = orig.m_options;
470  m_error_func = orig.m_error_func;
471  m_error_arg = orig.m_error_arg;
472  if (m_error_func != NULL)
473  {
475  }
476  return NXreopen(orig.m_fileid, &m_fileid);
477 }
478 
480 {
481  IXNeXusFile* the_clone = new IXNeXusFile();
482  the_clone->clone(*this);
483  return the_clone;
484 }
485 
486 
487 int IXNeXusFile::open(const char* filename, int mode, int type)
488 {
489  if (mode == IXNeXusFile::Update)
490  {
491  return NXopen(filename, NXACC_RDWR, &m_fileid);
492  }
493  else if (mode == IXNeXusFile::Write)
494  {
495  remove(filename);
496  if (type == IXNeXusFile::HDF5)
497  {
498  return NXopen(filename, NXACC_CREATE5, &m_fileid);
499  }
500  else
501  {
502  return NXopen(filename, NXACC_CREATE, &m_fileid);
503  }
504  }
505  else if (mode == IXNeXusFile::Read)
506  {
507  return NXopen(filename, NXACC_READ, &m_fileid);
508  }
509  else
510  {
511  m_fileid = 0;
512  return IXNeXusFile::Error;
513  }
514 }
515 
516 
517 
518 int IXNeXusFile::getLink(const char* name, const char* nxclass, NXlink& link)
519 {
520  if (NXopendata(m_fileid, name) == NX_OK)
521  {
522  NXgetdataID(m_fileid, &link);
523  return NXclosedata(m_fileid);
524  }
525  else if (NXopengroup(m_fileid, name, nxclass) == NX_OK)
526  {
527  NXgetgroupID(m_fileid, &link);
528  return NXclosegroup(m_fileid);
529  }
530  else
531  {
532  return NX_ERROR;
533  }
534 }
535 
536 int IXNeXusFile::makeLink(const char* name, const char* nxclass, NXlink& link)
537 {
538  if (name != NULL)
539  {
540  return NXmakenamedlink(m_fileid, name, &link);
541  }
542  else
543  {
544  return NXmakelink(m_fileid, &link);
545  }
546 }
547 
549 {
550  return NXclose(&m_fileid);
551 }
552 
553 
554 int IXNeXusFile::addSlab(const char* data_name, const int* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size, const int* dest_start)
555 {
556  return ::addSlab<int,NX_INT32>(m_fileid, data_name, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
557 }
558 
559 int IXNeXusFile::addSlab(const char* data_name, const unsigned long* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size, const int* dest_start)
560 {
561  return ::addSlab<unsigned long,NX_INT32>(m_fileid, data_name, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
562 }
563 
564 int IXNeXusFile::addSlab(const char* data_name, const float* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size, const int* dest_start)
565 {
566  return ::addSlab<float,NX_FLOAT32>(m_fileid, data_name, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
567 }
568 
569 int IXNeXusFile::addSlab(const int* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size, const int* dest_start)
570 {
571  return ::addSlab<int,NX_INT32>(m_fileid, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
572 }
573 
574 int IXNeXusFile::addSlab(const unsigned long* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size, const int* dest_start)
575 {
576  return ::addSlab<unsigned long,NX_INT32>(m_fileid, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
577 }
578 
579 int IXNeXusFile::addSlab(const float* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size, const int* dest_start)
580 {
581  return ::addSlab<float,NX_FLOAT32>(m_fileid, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
582 }
583 
584 int IXNeXusFile::addSlab(const int* value, const int64_t* dims_array, int ndims, const int64_t* slab_start, const int64_t* slab_size, const int64_t* dest_start)
585 {
586  return ::addSlab<int,NX_INT32>(m_fileid, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
587 }
588 
589 int IXNeXusFile::addSlab(const float* value, const int64_t* dims_array, int ndims, const int64_t* slab_start, const int64_t* slab_size, const int64_t* dest_start)
590 {
591  return ::addSlab<float,NX_FLOAT32>(m_fileid, value, dims_array, ndims, slab_start, slab_size, dest_start, m_compression_type);
592 }
593 
594 int IXNeXusFile::writeData(const char* data_name, int value)
595 {
596  return ::writeData<int,NX_INT32>(m_fileid, data_name, value, testOptions(WriteDummyOnNULL), m_compression_type);
597 }
598 
599 int IXNeXusFile::writeData(const char* data_name, uint64_t value)
600 {
601  return ::writeData<uint64_t,NX_UINT64>(m_fileid, data_name, value, testOptions(WriteDummyOnNULL), m_compression_type);
602 }
603 
604 int IXNeXusFile::writeData(const char* data_name, int64_t value)
605 {
606  return ::writeData<int64_t,NX_INT64>(m_fileid, data_name, value, testOptions(WriteDummyOnNULL), m_compression_type);
607 }
608 
609 int IXNeXusFile::writeData(const char* data_name, const uint64_t* value, const int* dims_array, int ndims)
610 {
611  return ::writeData<uint64_t,NX_UINT64>(m_fileid, data_name, value, dims_array, ndims, testOptions(WriteDummyOnNULL), m_compression_type);
612 }
613 
614 int IXNeXusFile::writeData(const char* data_name, const int64_t* value, const int* dims_array, int ndims)
615 {
616  return ::writeData<int64_t,NX_INT64>(m_fileid, data_name, value, dims_array, ndims, testOptions(WriteDummyOnNULL), m_compression_type);
617 }
618 
619 int IXNeXusFile::writeData(const char* data_name, const int* value, const int* dims_array, int ndims)
620 {
621  return ::writeData<int,NX_INT32>(m_fileid, data_name, value, dims_array, ndims, testOptions(WriteDummyOnNULL), m_compression_type);
622 }
623 
624 int IXNeXusFile::writeData(const char* data_name, const unsigned int* value, const int* dims_array, int ndims)
625 {
626  return ::writeData<unsigned int,NX_UINT32>(m_fileid, data_name, value, dims_array, ndims, testOptions(WriteDummyOnNULL), m_compression_type);
627 }
628 
629 int IXNeXusFile::writeData(const char* data_name, const uint64_t* value, int len)
630 {
631  return ::writeData<uint64_t,NX_UINT64>(m_fileid, data_name, value, len, testOptions(WriteDummyOnNULL), m_compression_type);
632 }
633 
634 int IXNeXusFile::writeData(const char* data_name, const int64_t* value, int len)
635 {
636  return ::writeData<int64_t,NX_INT64>(m_fileid, data_name, value, len, testOptions(WriteDummyOnNULL), m_compression_type);
637 }
638 
639 int IXNeXusFile::writeData(const char* data_name, const int* value, int len)
640 {
641  return ::writeData<int,NX_INT32>(m_fileid, data_name, value, len, testOptions(WriteDummyOnNULL), m_compression_type);
642 }
643 
644 int IXNeXusFile::writeData(const char* data_name, const unsigned int* value, int len)
645 {
646  return ::writeData<unsigned int,NX_UINT32>(m_fileid, data_name, value, len, testOptions(WriteDummyOnNULL), m_compression_type);
647 }
648 
649 int IXNeXusFile::writeData(const char* data_name, const int* value, int dim1, int dim2)
650 {
651  return ::writeData<int,NX_INT32>(m_fileid, data_name, value, dim1, dim2, testOptions(WriteDummyOnNULL), m_compression_type);
652 }
653 
654 int IXNeXusFile::writeSlab(const char* data_name, const int* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size)
655 {
656  return ::writeSlab<int,NX_INT32>(m_fileid, data_name, value, dims_array, ndims, slab_start, slab_size, testOptions(WriteDummyOnNULL), m_compression_type);
657 }
658 
659 int IXNeXusFile::writeSlabList(const char* data_name, const unsigned long* value, const int* dims_array, int ndims, const int* slab_start, const int* slab_size, const std::vector<int>& slab_list)
660 {
661  return ::writeSlabList<unsigned long,NX_INT32>(m_fileid, data_name, value, dims_array, ndims, slab_start, slab_size, slab_list, testOptions(WriteDummyOnNULL), m_compression_type, m_spectra_chunk);
662 }
663 
664 int IXNeXusFile::addSlabList(const char* data_name, const unsigned long* value, const int* dims_array, int ndims, int dest_start[], const int* slab_start, const int* slab_size, const std::vector<int>& slab_list)
665 {
666  return ::addSlabList<unsigned long,NX_INT32>(m_fileid, data_name, value, dims_array, ndims, dest_start, slab_start, slab_size, slab_list, testOptions(WriteDummyOnNULL), m_compression_type, m_spectra_chunk);
667 }
668 
669 int IXNeXusFile::makeDataSlab(const char* data_name, const unsigned long* value, const int* slab_size, int ndims)
670 {
671  return ::makeDataSlab<NX_INT32>(m_fileid, data_name, slab_size, ndims, m_compression_type, m_spectra_chunk);
672 }
673 
674 
675 int IXNeXusFile::writeData(const char* data_name, float value)
676 {
677  return ::writeData<float,NX_FLOAT32>(m_fileid, data_name, value, testOptions(WriteDummyOnNULL), m_compression_type);
678 }
679 
680 int IXNeXusFile::writeData(const char* data_name, const float* value, const int* dims_array, int ndims)
681 {
682  return ::writeData<float,NX_FLOAT32>(m_fileid, data_name, value, dims_array, ndims, testOptions(WriteDummyOnNULL), m_compression_type);
683 }
684 
685 int IXNeXusFile::writeData(const char* data_name, const float* value, int len)
686 {
687  return ::writeData<float,NX_FLOAT32>(m_fileid, data_name, value, len, testOptions(WriteDummyOnNULL), m_compression_type);
688 }
689 
690 int IXNeXusFile::writeData(const char* data_name, const float* value, int dim1, int dim2)
691 {
692  return ::writeData<float,NX_FLOAT32>(m_fileid, data_name, value, dim1, dim2, testOptions(WriteDummyOnNULL), m_compression_type);
693 }
694 
695 int IXNeXusFile::writeData(const char* data_name, double value)
696 {
697  return ::writeData<double,NX_FLOAT64>(m_fileid, data_name, value, testOptions(WriteDummyOnNULL), m_compression_type);
698 }
699 
700 int IXNeXusFile::writeData(const char* data_name, const double* value, const int* dims_array, int ndims)
701 {
702  return ::writeData<double,NX_FLOAT64>(m_fileid, data_name, value, dims_array, ndims, testOptions(WriteDummyOnNULL), m_compression_type);
703 }
704 
705 int IXNeXusFile::writeData(const char* data_name, const double* value, int len)
706 {
707  return ::writeData<double,NX_FLOAT64>(m_fileid, data_name, value, len, testOptions(WriteDummyOnNULL), m_compression_type);
708 }
709 
710 int IXNeXusFile::writeData(const char* data_name, const double* value, int dim1, int dim2)
711 {
712  return ::writeData<double,NX_FLOAT64>(m_fileid, data_name, value, dim1, dim2, testOptions(WriteDummyOnNULL), m_compression_type);
713 }
714 
715 int IXNeXusFile::writeData(const char* data_name, const char* value, int dim1, int dim2)
716 {
717  return ::writeData<char,NX_CHAR>(m_fileid, data_name, value, dim1, dim2, testOptions(WriteDummyOnNULL), m_compression_type);
718 }
719 
720 int IXNeXusFile::writeData(const char* data_name, const char* value, int len)
721 {
722  return ::writeData<char,NX_CHAR>(m_fileid, data_name, value, &len, 1, testOptions(WriteDummyOnNULL), m_compression_type);
723 }
724 
725 int IXNeXusFile::writeData(const char* data_name, const char* value)
726 {
727  return writeData(data_name, value, strlen(value));
728 }
729 
730 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, int value)
731 {
732  return ::writeAttribute<int,NX_INT32>(m_fileid, data_name, attr_name, value, testOptions(WriteDummyOnNULL));
733 }
734 
735 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, const int* value, int len)
736 {
737  return ::writeAttribute<int,NX_INT32>(m_fileid, data_name, attr_name, value, len, testOptions(WriteDummyOnNULL));
738 }
739 
740 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, float value)
741 {
742  return ::writeAttribute<float,NX_FLOAT32>(m_fileid, data_name, attr_name, value, testOptions(WriteDummyOnNULL));
743 }
744 
745 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, const float* value, int len)
746 {
747  return ::writeAttribute<float,NX_FLOAT32>(m_fileid, data_name, attr_name, value, len, testOptions(WriteDummyOnNULL));
748 }
749 
750 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, double value)
751 {
752  return ::writeAttribute<double,NX_FLOAT64>(m_fileid, data_name, attr_name, value, testOptions(WriteDummyOnNULL));
753 }
754 
755 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, const double* value, int len)
756 {
757  return ::writeAttribute<double,NX_FLOAT64>(m_fileid, data_name, attr_name, value, len, testOptions(WriteDummyOnNULL));
758 }
759 
760 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, const char* value, int len)
761 {
762  return ::writeAttribute<char,NX_CHAR>(m_fileid, data_name, attr_name, value, len, testOptions(WriteDummyOnNULL));
763 }
764 
765 int IXNeXusFile::writeAttribute(const char* data_name, const char* attr_name, const char* value)
766 {
767  return writeAttribute(data_name, attr_name, value, strlen(value));
768 }
769 
770 
771 int IXNeXusFile::makeNewGroup(const char* name, const char* nxclass, bool open_group)
772 {
773  NXmakegroup(m_fileid, name, (char*)nxclass);
774  if (open_group)
775  {
776  NXopengroup(m_fileid, name, (char*)nxclass);
777  }
778  return 0;
779 }
780 
782 {
783  NXclosegroup(m_fileid);
784  return 0;
785 }
786 
787 const char* IXNeXusFile::ISOtime(time_t time)
788 {
789  static char buffer[256];
790  struct tm *tm_struct;
791  tm_struct = localtime(&time);
792  if (tm_struct != 0)
793  {
794  strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", tm_struct);
795  }
796  else
797  {
798  strncpy(buffer, "<UNKNOWN>", sizeof(buffer));
799  }
800  buffer[sizeof(buffer)-1] = '\0';
801  return buffer;
802 }
803 
804 // return 1 if OK, 0 on error
805 static int readDeadTimes(float* deadtimes_array, int ndet, const char* file)
806 {
807  int i, n = 0;
808  memset(deadtimes_array, 0, ndet*sizeof(float));
809  std::fstream f;
810  f.open(file, std::ios::in);
811  if (!f.good())
812  {
813  return 0;
814  }
815  f >> n;
816  if (n != ndet)
817  {
818  f.close();
819  return 0;
820  }
821  n = 0;
822  while(f.good() && n < ndet)
823  {
824  f >> i;
825  if ((i >= 1) && (i <= ndet))
826  {
827  f >> deadtimes_array[i-1];
828  }
829  n++;
830  }
831  f.close();
832  if (n != ndet)
833  {
834  return 0;
835  }
836  else
837  {
838  return 1;
839  }
840 }
841 
842 // return 1 if OK, 0 on error
843 static int readTZero(float& tzero, float& tzero_offset, const char* file)
844 {
845  int stat = 0;
846  tzero = 0.0f, tzero_offset = 0.1f;
847  std::fstream f;
848  f.open(file, std::ios::in);
849  if ( f.good() )
850  {
851  f.ignore(50000, '\n'); // skip first line
852  f >> tzero;
853  if ( f.good() )
854  {
855  stat = 1;
856  }
857  // tzero_offset may or may not be here, use 0.1 if not present
858  // if read failed, it will still be 0.1 - we can't check for f.good() as that relies on a blank line at end of file
859  f >> tzero_offset;
860  f.close();
861  }
862  return stat;
863 }
864 
865 // 0 on error
866 static int readGrouping(int* grouping, int ndet, const char* file)
867 {
868  int i, j, k, m, n, ngroup, group_type;
869  float alpha;
870  for(i=0; i<ndet; i++)
871  {
872  grouping[i] = 0;
873  }
874  std::fstream f;
875  f.open(file, std::ios::in);
876  f.ignore(50000, '\n'); // skip first line
877  n = 0;
878  f >> n;
879  f.ignore(50000, '\n'); // skip rest of line
880  if (n != ndet)
881  {
882  return 0;
883  }
884  for(i=0; i<ndet; i++)
885  {
886  f.ignore(50000, '\n'); // ignore rest of line
887  f.ignore(50000, '\n'); // ignore rest of line
888  }
889  int group = 1;
890  f >> group_type; // 1=simple, 2=forward-backward
891  f.ignore(50000, '\n'); // ignore rest of line
892  f.ignore(50000, '\n'); // ignore next line
893  ngroup = 0;
894  f >> ngroup;
895  f.ignore(50000, '\n'); // ignore rest of line
896  k = 0;
897  for(i=1; i <= ngroup; i++)
898  {
899  if (group_type == 1)
900  {
901  f.ignore(50000, '\n'); // ignore rest of line
902  f >> n;
903  f.ignore(50000, '\n'); // ignore rest of line
904  for(j=0; j<n; j++)
905  {
906  f >> k;
907  if ((k >=1) && (k <= ndet))
908  {
909  grouping[k-1] = i;
910  }
911  }
912  f.ignore(50000, '\n'); // ignore rest of line
913  }
914  else if (group_type == 2)
915  {
916  f.ignore(50000, '\n'); // ignore rest of line
917  for(m=1; m <= 2; m++)
918  {
919  f >> n;
920  f.ignore(50000, '\n'); // ignore rest of line
921  for(j=0; j<n; j++)
922  {
923  f >> k;
924  if ((k >=1) && (k <= ndet))
925  {
926  grouping[k-1] = m + 2*(i-1);
927  }
928  }
929  f.ignore(50000, '\n'); // ignore rest of line
930  }
931  f >> alpha;
932  f.ignore(50000, '\n'); // ignore rest of line
933  }
934  }
935  return ngroup;
936 }
937 
938 static void nxErrorFunc(void* arg, char* text)
939 {
940  DAEstatus* pStatus = (DAEstatus*)arg;
941  pStatus->addVa(FAC_CRPT, SEV_ERROR, ERRTYPE_OUTOFMEM, "NEXUS ERROR: %s", text);
942 }
943 
944 
945 static void computeDetectorAverage(const float* det_vals, float* spec_vals, const std::vector<int>* det_lookup, const std::vector<int>& spec_list)
946 {
947  int i, j, n;
948  float val;
949  for(i=0; i < spec_list.size(); i++)
950  {
951  val = 0.0;
952  const std::vector<int>& dvec = det_lookup[spec_list[i]];
953  n = dvec.size();
954  for(j = 0; j<n; j++)
955  {
956  val += det_vals[dvec[j]];
957  }
958  if (n > 0)
959  {
960  spec_vals[i] = val / static_cast<float>(n);
961  }
962  else
963  {
964  spec_vals[i] = 9999.0;
965  }
966  }
967 }
968 
969 static int addMonitors(IXNeXusFile& ixnf, const ISISCRPT_STRUCT* crpt, const isisU32_t* raw_data, isisU32_t raw_data_size, NXlink* tof_links, NXlink& period_link, bool update, DAEstatus& dstatus)
970 {
971  using namespace NeXus;
972  using namespace NeXus::Stream;
973  File nxf(ixnf.fileid());
974  char name[128];
975  int mon_spec, mon_number, mon_tr;
976  for(int i=0; i<crpt->nmon; i++)
977  {
978  mon_number = i + 1;
979  _snprintf(name, sizeof(name), "monitor_%d", mon_number);
980  if (crpt->mdet[i] == 0)
981  {
982  dstatus.addWarningVa(FAC_DAE, "Skipping monitor %d - not properly defined in wiring table", mon_number);
983  continue;
984  }
985  mon_spec = crpt->monitorNumberToSpectrum(mon_number);
986  mon_tr = crpt->spectrumCRPTTR(mon_spec);
987  int ntc = crpt->spectrumNTC(mon_spec);
988  isisU32_t* monitor_data = new isisU32_t[crpt->nper_daq * ntc]; // we ignore time bin zero
989  for(int j=0; j<crpt->nper_daq; ++j)
990  {
991  uint32_t offset = crpt->spectrumCRPTOffsetImpl(mon_spec, j, raw_data_size);
992  memcpy(monitor_data + j*ntc, raw_data + offset + 1, ntc * sizeof(isisU32_t)); // +1 to offset to skip bin 0
993  }
994  int data_size[3] = { crpt->nper_daq, 1, ntc };
995  if (update)
996  {
997  nxf >> Group(name, "NXmonitor");
998  }
999  else
1000  {
1001  nxf << Group(name, "NXmonitor");
1002  }
1003  ixnf.writeData("monitor_number", mon_number);
1004  ixnf.writeData("data", reinterpret_cast<int*>(monitor_data), data_size, 3);
1005  ixnf.writeAttribute("data", "units", "counts");
1006  ixnf.writeAttribute("data", "signal", 1);
1007  ixnf.writeAttribute("data", "axes", "period_index,spectrum_index,time_of_flight");
1008  ixnf.makeLink(NULL, tof_links[mon_tr-1]);
1009  ixnf.makeLink(NULL, period_link);
1010  ixnf.writeData("spectrum_index", mon_spec);
1011 // ixnf.writeData("distance", crpt->len2[crpt->mdet[i] - 1]); /// @todo this needs to average properly
1012  nxf << Close;
1013  delete[] monitor_data;
1014  }
1015  return 0;
1016 }
1017 
1018 static int writeSummaryNeXus(const ISISCRPT_STRUCT* crpt, DAEstatus& dstatus)
1019 {
1020  long first_run_number;
1021  char buffer[256];
1022  char measurement_line[80];
1023  int nx_mode;
1024  std::string label;
1025  std::stringstream string_str;
1026  std::vector<int> dims(2), slab_start(2), slab_size(2);
1027  dims[0] = NX_UNLIMITED;
1028  dims[1] = sizeof(measurement_line);
1029  slab_start[0] = 0;
1030  slab_start[1] = 0;
1031  slab_size[0] = 1;
1032  slab_size[1] = dims[1];
1033  if (strlen(crpt->measurement_id) == 0)
1034  {
1035  return 0;
1036  }
1037  if (se_get_measurement_first_run(crpt->measurement_id, first_run_number) != 0)
1038  {
1039  return -1;
1040  }
1041  if (se_get_measurement_label(crpt->measurement_id, label) != 0)
1042  {
1043  return -1;
1044  }
1045 // string_str << "c:\\data\\measurement_" << label << ".nxs";
1046  string_str << "c:\\data\\measurement.nxs";
1047  std::string file(string_str.str());
1048  if (access(file.c_str(), 0) == 0)
1049  {
1050  nx_mode = NXACC_RDWR;
1051  }
1052  else
1053  {
1054  nx_mode = NXACC_CREATE5;
1055  }
1056  sprintf(buffer, "%08d", first_run_number);
1057  string_str << "entry_" << buffer;
1058  try
1059  {
1060  NeXus::File nf(file, nx_mode);
1061  if (nx_mode != NXACC_RDWR)
1062  {
1063  nf.makeGroup("entry_1", "NXentry", true);
1064  nf.makeData("measurement_id", NeXus::CHAR, dims);
1065  nf.makeData("measurement_subid", NeXus::CHAR, dims);
1066  nf.makeData("measurement_type", NeXus::CHAR, dims);
1067  nf.makeData("measurement_label", NeXus::CHAR, dims);
1068  nf.makeData("sample_id", NeXus::CHAR, dims);
1069  slab_start[0] = -1; // this is because size of the dimension willbe returned as 1 even though no data
1070  }
1071  else
1072  {
1073  nf.openGroup("entry_1", "NXentry");
1074  slab_start[0] = 0;
1075  }
1076  strncpy(measurement_line, crpt->measurement_id, sizeof(measurement_line));
1077  nf.openData("measurement_id");
1078  slab_start[0] += nf.getInfo().dims[0];
1079  if (slab_start[0] < 0) { slab_start[0] = 0; }
1080  nf.putSlab(measurement_line, slab_start, slab_size);
1081  nf.closeData();
1082  strncpy(measurement_line, label.c_str(), sizeof(measurement_line));
1083  nf.openData("measurement_label"); nf.putSlab(measurement_line, slab_start, slab_size); nf.closeData();
1084  strncpy(measurement_line, crpt->measurement_subid, sizeof(measurement_line));
1085  nf.openData("measurement_subid"); nf.putSlab(measurement_line, slab_start, slab_size); nf.closeData();
1086  strncpy(measurement_line, crpt->measurement_type, sizeof(measurement_line));
1087  nf.openData("measurement_type"); nf.putSlab(measurement_line, slab_start, slab_size); nf.closeData();
1088  strncpy(measurement_line, crpt->sample_id, sizeof(measurement_line));
1089  nf.openData("sample_id"); nf.putSlab(measurement_line, slab_start, slab_size); nf.closeData();
1090  nf.closeGroup();
1091  }
1092  catch(std::exception& ex)
1093  {
1094  dstatus.addWarningVa(FAC_CRPT, "Error writing measurement file %s", ex.what());
1095  }
1096  return 0;
1097 }
1098 
1099 const char* detector_base = "detector";
1100 const char* detector_format = "detector_%d";
1101 
1102 int NeXusWriter::writeISISNeXus(const char* filename, bool logs_only, const ISISCRPT_STRUCT* crpt, const isisU32_t* raw_data, isisU32_t raw_data_size, const ISISRAW* iraw, const seblock_map_t& blocks, const std::string& events_nxfile, const std::string& inst_xml_file, const std::string& inst_parameter_map_file, DAEstatus& dstatus)
1103 {
1104  int ret = writeISISNeXus(events_nxfile.c_str(), logs_only, crpt, raw_data, raw_data_size, iraw, blocks, inst_xml_file, inst_parameter_map_file, dstatus, true);
1105  rename(events_nxfile.c_str(), filename);
1106  return ret;
1107 }
1108 
1109 void NeXusWriter::readExternalFile(const std::string& file_name, std::string& file_contents)
1110 {
1111  file_contents = "";
1112  std::ifstream fs(file_name, std::ios::in);
1113  fs.seekg(0, std::ios::end);
1114  file_contents.reserve(fs.tellg());
1115  fs.seekg(0, std::ios::beg);
1116  file_contents.assign( (std::istreambuf_iterator<char>(fs)), std::istreambuf_iterator<char>() ); // need extra brackets to avoid "Most Vexing Parse" problem
1117  fs.close();
1118 }
1119 
1120 int NeXusWriter::writeISISNeXus(const char* filename, bool logs_only, const ISISCRPT_STRUCT* crpt, const isisU32_t* raw_data, isisU32_t raw_data_size, const ISISRAW* iraw, const seblock_map_t& blocks, const std::string& inst_xml_file, const std::string& inst_parameter_map_file, DAEstatus& dstatus, bool update)
1121 {
1122  static const char* entry_name = "raw_data_1";
1123  static const char* source_name = "source";
1124  IXNeXusFile nx_file;
1125  if ( Poco::Util::Application::instance().config().getBool("isisicp.snseventfile", false) )
1126  {
1127  entry_name = "entry";
1128  source_name = "SNS";
1129  detector_base = "bank";
1130  detector_format = "bank%d";
1131  }
1132  ICPTimer time_all;
1133  NXsetcache(64*1024*1024);
1135  nx_file.setErrorReporter(nxErrorFunc, (void*)&dstatus);
1136  int mode = (update ? IXNeXusFile::Update : IXNeXusFile::Write);
1137  if (nx_file.open(filename, mode, file_type) != NX_OK)
1138  {
1139  return 0;
1140  }
1142 // nx_file.enableOptions(IXNeXusFile::WriteDummyOnNULL);
1143  int i, j;
1144  std::string tmp_str;
1145  char buffer[256];
1146  if (file_type == IXNeXusFile::HDF5)
1147  {
1148  nx_file.enableCompression(100*NX_COMP_LZW + crpt->compression_level);
1149  dstatus.addInfoVa(FAC_DAE, "compression level = %d", crpt->compression_level);
1150  }
1152  dstatus.addInfoVa(FAC_DAE, "compression block size = %d", crpt->compression_block_size);
1153 
1154  // @todo should write creator global attribute now
1155 
1156  int persize = crpt->getPeriodSize();
1157  if (update)
1158  {
1159  nx_file.openGroup(entry_name, "NXentry");
1160  }
1161  else
1162  {
1163  nx_file.makeNewGroup(entry_name, "NXentry");
1164  }
1165  if (crpt->dae_type == ISISDAE::MuonDAE2)
1166  {
1167  nx_file.writeData("IDF_version", 2);
1168  nx_file.writeData("definition", "pulsedTD");
1169  nx_file.writeAttribute("definition", "version", "1.0");
1170  nx_file.writeAttribute("definition", "url", "http://definition.nexusformat.org/instruments/pulsedTD?version=1.0");
1171  }
1172  else
1173  {
1174  nx_file.writeData("definition", "TOFRAW");
1175  nx_file.writeAttribute("definition", "version", "1.0");
1176  nx_file.writeAttribute("definition", "url", "http://definition.nexusformat.org/instruments/TOFRAW?version=1.0");
1177  nx_file.writeData("definition_local", "ISISTOFRAW");
1178  nx_file.writeAttribute("definition_local", "version", "1.0");
1179  nx_file.writeAttribute("definition_local", "url", "http://svn.isis.rl.ac.uk/instruments/ISISTOFRAW?version=1.0");
1180  }
1181 
1182  nx_file.writeData("program_name", "ISISICP.EXE");
1183  nx_file.writeAttribute("program_name", "version", crpt->icp_version);
1184  nx_file.writeData("run_number", crpt->run_number);
1185  nx_file.writeData("run_cycle", crpt->isis_cycle);
1186  nx_file.writeData("title", crpt->long_title /*, sizeof(crpt->long_title)*/ );
1187  nx_file.writeData("notes", crpt->comment);
1188  nx_file.writeData("name", crpt->inst_name);
1189  nx_file.writeAttribute("name", "short_name", crpt->inst_abrv);
1190  nx_file.writeData("beamline", crpt->inst_name /* , sizeof(crpt->inst_name)*/ );
1191  nx_file.writeData("start_time", nx_file.ISOtime(crpt->start_time));
1192  nx_file.writeAttribute("start_time", "units", "ISO8601");
1193  nx_file.writeData("end_time", nx_file.ISOtime(crpt->stop_time));
1194  nx_file.writeAttribute("end_time", "units", "ISO8601");
1195  nx_file.writeData("duration", (float)crpt->duration);
1196  nx_file.writeAttribute("duration", "units", "second");
1197  // slightly complicated as need to know which target station, but could also
1198  // be runnign chopper at less that target frequency
1199  // nx_file.writeData("collection_time", (float)crpt->good_frames / (float)50.0);
1200  nx_file.writeData("collection_time", (float)crpt->duration);
1201  nx_file.writeAttribute("collection_time", "units", "second");
1202 
1203  nx_file.writeData("proton_charge", crpt->good_uamph);
1204  nx_file.writeAttribute("proton_charge", "units", "uAh");
1205  nx_file.writeData("proton_charge_raw", crpt->total_uamph);
1206  nx_file.writeAttribute("proton_charge_raw", "units", "uAh");
1207  nx_file.writeData("good_frames", crpt->good_frames);
1208  nx_file.writeData("raw_frames", crpt->total_frames);
1209  sprintf(buffer, "%d", crpt->rb_number);
1210  nx_file.writeData("experiment_identifier", buffer);
1211 
1212  std::string seci_config;
1213  se_get_seci_config(seci_config);
1214  nx_file.writeData("seci_config", seci_config);
1215 
1216  long first_run_number;
1217  if (se_get_measurement_first_run(crpt->measurement_id, first_run_number) != 0)
1218  {
1219  first_run_number = 0;
1220  }
1221  std::string measurement_label;
1222  if (se_get_measurement_label(crpt->measurement_id, measurement_label) != 0)
1223  {
1224  measurement_label = "";
1225  }
1226  nx_file.writeData("measurement_id", crpt->measurement_id);
1227  nx_file.writeData("measurement_subid", crpt->measurement_subid);
1228  nx_file.writeData("measurement_type", crpt->measurement_type);
1229  nx_file.writeData("measurement_first_run", (int)first_run_number);
1230  nx_file.writeData("measurement_label", measurement_label.c_str());
1231 
1232  nx_file.writeData("script_name", crpt->script_name);
1233 
1234  nx_file.makeNewGroup("user_1","NXuser");
1235  nx_file.writeData("name", crpt->user_name);
1236  nx_file.writeData("affiliation", crpt->institute);
1237  nx_file.closeGroup(); // NXuser
1238 
1239  nx_file.makeNewGroup("sample","NXsample");
1240  nx_file.writeData("name", crpt->sample_name);
1241  nx_file.writeData("distance", 0.0);
1242  nx_file.writeData("id", crpt->sample_id);
1243  nx_file.writeData("thickness", crpt->sample_thickness);
1244  nx_file.writeData("width", crpt->sample_width);
1245  nx_file.writeData("height", crpt->sample_height);
1246  nx_file.writeData("type", crpt->sample_type);
1247  nx_file.writeData("shape", crpt->sample_geometry);
1248 
1249  nx_file.closeGroup(); // NXsample
1250  nx_file.makeNewGroup("periods","IXperiods");
1251  unsigned long sum = 0;
1252  // sum all except spectrum 0
1253  int* period_sum = new int[crpt->nper]; // not nper_daq as we use array later
1254  float* period_fsum = new float[crpt->nper]; // not nper_daq as we use array later
1255  float* total_counts_period = new float[crpt->nper_daq];
1256  for(j=0; j<crpt->nper_daq; j++)
1257  {
1258  period_sum[j] = 0;
1259  for(i=crpt->ntc[0] + 1; i < persize; i++)
1260  {
1261  period_sum[j] += raw_data[i+j*persize];
1262  }
1263  sum += period_sum[j];
1264  total_counts_period[j] = (float)period_sum[j] / (float)1e6;
1265  }
1266  nx_file.writeData("number", crpt->nper);
1267  // nx_file.writeData("total_counts", (float)sum / (float)1e6);
1268  // nx_file.writeAttribute("total_counts", "units", "Mev");
1269  nx_file.writeData("total_counts", total_counts_period, crpt->nper_daq); // nonstandard
1270  nx_file.writeAttribute("total_counts", "units", "Mev"); // nonstandard
1271  delete[] total_counts_period;
1272 
1273  for(j=0; j<crpt->nper; j++)
1274  {
1275  period_sum[j] = crpt->period[j].good_frames;
1276  }
1277  nx_file.writeData("good_frames", period_sum, crpt->nper); // nonstandard
1278  for(j=0; j<crpt->nper; j++)
1279  {
1280  period_sum[j] = crpt->period[j].total_frames;
1281  }
1282  nx_file.writeData("raw_frames", period_sum, crpt->nper); // nonstandard
1283 
1284  for(j=0; j<crpt->nper; j++)
1285  {
1286  period_fsum[j] = crpt->period[j].good_uamph;
1287  }
1288  nx_file.writeData("proton_charge", period_fsum, crpt->nper); // nonstandard
1289  nx_file.writeAttribute("proton_charge", "units", "uAh");
1290  for(j=0; j<crpt->nper; j++)
1291  {
1292  period_fsum[j] = crpt->period[j].total_uamph;
1293  }
1294  nx_file.writeData("proton_charge_raw", period_fsum, crpt->nper); // nonstandard
1295  nx_file.writeAttribute("proton_charge_raw", "units", "uAh");
1296 
1297  i=0;
1298  for(j=0; j<crpt->nper; j++)
1299  {
1300  if (crpt->period[j].daq_period >= 0)
1301  {
1302  period_sum[i++] = crpt->period[j].good_frames;
1303  }
1304  }
1305  nx_file.writeData("good_frames_daq", period_sum, crpt->nper_daq); // nonstandard
1306  sum = 0;
1307  for(i=0; i<crpt->nper_daq; i++)
1308  {
1309  sum += period_sum[i];
1310  }
1311  // if (crpt->nper == 1) // assume no period card
1312  // {
1313  // nx_file.writeData("frames", crpt->good_frames);
1314  // }
1315  // else // assume period card
1316  // {
1317  // nx_file.writeData("frames", (int)(sum / crpt->nper_daq)); // assumes equal numbers of frames per daq period
1318  // }
1319  // nx_file.writeData("frames_good", crpt->good_frames); // nonstandard
1320  // nx_file.writeData("frames_raw", crpt->total_frames); // nonstandard
1322  for(j=0; j<crpt->nper; j++)
1323  {
1324  period_sum[j] = crpt->nperseq;
1325  }
1326  nx_file.writeData("sequences", period_sum, crpt->nper); // nonstandard
1327  for(j=0; j<crpt->nper; j++)
1328  {
1329  period_sum[j] = crpt->period[j].requested_frames;
1330  }
1331  nx_file.writeData("frames_requested", period_sum, crpt->nper); // nonstandard
1332  for(j=0; j<crpt->nper; j++)
1333  {
1334  period_sum[j] = crpt->period[j].type;
1335  }
1336  nx_file.writeData("type", period_sum, crpt->nper); // nonstandard
1337  for(j=0; j<crpt->nper; j++)
1338  {
1339  period_sum[j] = crpt->period[j].output;
1340  }
1341  nx_file.writeData("output", period_sum, crpt->nper); // nonstandard
1342  tmp_str = crpt->period[0].label;
1343  for(j=1; j<crpt->nper; j++)
1344  {
1345  tmp_str.append(";");
1346  tmp_str.append(crpt->period[j].label);
1347  }
1348  nx_file.writeData("labels", tmp_str.c_str()); // nonstandard
1349  delete[] period_sum;
1350  delete[] period_fsum;
1351  nx_file.closeGroup(); // IXperiods
1352  if (update)
1353  {
1354  nx_file.openGroup("instrument","NXinstrument");
1355  }
1356  else
1357  {
1358  nx_file.makeNewGroup("instrument","NXinstrument");
1359  }
1360  nx_file.writeData("name", crpt->inst_name);
1361  nx_file.writeAttribute("name", "short_name", crpt->inst_abrv);
1362 
1363  if ( (strlen(crpt->instrument_xml_file) > 0) && (access(inst_xml_file.c_str(), 4 /* R_OK */) == 0) )
1364  {
1365  try
1366  {
1367  std::string inst_xml, inst_parameter_map;
1368  std::string detector_calibration_file = crpt->detector_table.fname; // our "detector.dat" which is a Mantid intermediate file
1369  readExternalFile(inst_xml_file, inst_xml);
1370  readExternalFile(inst_parameter_map_file, inst_parameter_map);
1371  nx_file.makeNewGroup("instrument_xml", "NXnote");
1372  nx_file.writeData("data", inst_xml);
1373  nx_file.writeData("type", "text/xml");
1374  nx_file.writeData("description", "Mantid Instrument IDF copied from " + detector_calibration_file);
1375  nx_file.closeGroup();
1376  nx_file.makeNewGroup("instrument_parameter_map", "NXnote");
1377  nx_file.writeData("data", inst_parameter_map);
1378  nx_file.writeData("type", "text/plain");
1379  nx_file.writeData("description", "Mantid Instrument parameters copied from " + detector_calibration_file);
1380  nx_file.closeGroup();
1381  nx_file.writeData("instrument_source", crpt->instrument_xml_file);
1382  nx_file.writeData("instrument_detector_calibration_file", detector_calibration_file);
1383  }
1384  catch(const std::exception& ex)
1385  {
1386  LOGSTR_ERROR("Cannot load instrument XML: " << ex.what());
1387  }
1388  }
1389 
1390  nx_file.makeNewGroup(source_name,"NXsource");
1391  nx_file.writeData("name", "ISIS");
1392  if (crpt->dae_type == ISISDAE::MuonDAE2)
1393  {
1394  nx_file.writeData("type", "Pulsed Muon Source");
1395  nx_file.writeData("probe", "muons");
1396  }
1397  else
1398  {
1399  nx_file.writeData("type", "Pulsed Neutron Source");
1400  nx_file.writeData("probe", "neutrons");
1401  }
1402  nx_file.closeGroup(); // NXsource
1403  if (crpt->dae_type != ISISDAE::MuonDAE2)
1404  {
1405  nx_file.makeNewGroup("moderator","NXmoderator");
1406  nx_file.writeData("distance", -(crpt->i_l1));
1407  nx_file.writeAttribute("distance", "units", "metre");
1408  nx_file.closeGroup(); // NXmoderator
1409  }
1410  NXlink period_link, tof_links[ISISCRPT_MAX_NTRG], tof_raw_links[ISISCRPT_MAX_NTRG];
1411  if (update)
1412  {
1413  nx_file.openGroup("dae", "IXdae");
1414  }
1415  else
1416  {
1417  nx_file.makeNewGroup("dae", "IXdae");
1418  }
1419  nx_file.writeData("detector_table_file", crpt->detector_table.fname);
1420  nx_file.writeData("spectra_table_file", crpt->spectra_table.fname);
1421  nx_file.writeData("wiring_table_file", crpt->wiring_table.fname);
1422  nx_file.makeNewGroup("vetos", "IXvetos");
1423  for(i=0; i<ISISCRPT_NUM_VETOS; i++)
1424  {
1425  nx_file.writeData(veto_names[i], crpt->vetos[i].frames);
1426  nx_file.writeAttribute(veto_names[i], "enabled", crpt->vetos[i].enabled);
1427  }
1428  nx_file.closeGroup(); // IXvetos
1429  for(j=0; j<crpt->ntrg; j++)
1430  {
1431  sprintf(buffer, "time_channels_%d", j+1);
1432  if (update)
1433  {
1434  nx_file.openGroup(buffer, "IXtime_channels");
1435  }
1436  else
1437  {
1438  nx_file.makeNewGroup(buffer, "IXtime_channels");
1439  nx_file.writeData("time_of_flight", &(crpt->rtcb[j][0]), 1 + crpt->ntc[j]);
1440  nx_file.writeAttribute("time_of_flight", "axis", 1);
1441  nx_file.writeAttribute("time_of_flight", "primary", 1);
1442  nx_file.writeAttribute("time_of_flight", "units", "microsecond");
1443  nx_file.writeData("time_of_flight_raw", &(crpt->tcb[j][0]), 1 + crpt->ntc[j]);
1444  nx_file.writeAttribute("time_of_flight_raw", "units", "pulses");
1445  nx_file.writeAttribute("time_of_flight_raw", "frequency", "32 MHz");
1446  }
1447  nx_file.getLink("time_of_flight", tof_links[j]);
1448  nx_file.getLink("time_of_flight_raw", tof_raw_links[j]);
1449  nx_file.closeGroup(); // IXtime_channels
1450  }
1451  std::vector<int> period_no(crpt->nper_daq);
1452  for(i=0; i<crpt->nper_daq; i++)
1453  {
1454  period_no[i] = i+1;
1455  }
1456  nx_file.writeData("period_index", &(period_no[0]), crpt->nper_daq);
1457  nx_file.getLink("period_index", period_link);
1458  nx_file.closeGroup(); // IXdae
1459  nx_file.closeGroup(); // NXinstrument
1460  NXlink counts_link, spec_link;
1461  ICPTimer time_detector;
1462  std::vector<int>* det_lookup = new std::vector<int>[crpt->getNumSpectra(true)];
1463  for(i=0; i<crpt->ndet; i++)
1464  {
1465  det_lookup[crpt->spec[i]].push_back(i);
1466  }
1467  float* spec_work = new float[crpt->getNumSpectra(true)];
1468  std::set<int> spec_groups;
1469  for(i=0; i<crpt->ndet; ++i)
1470  {
1471  int spec = crpt->spec[i];
1472  spec_groups.insert(crpt->spectrumGroup(spec));
1473  }
1474  for(i=0; i<crpt->ntrg; ++i)
1475  {
1476  spec_groups.insert(i+1);
1477  }
1478  nx_file.openGroup("instrument", "NXinstrument");
1479  if (!update)
1480  {
1481  BOOST_FOREACH(int group_index, spec_groups)
1482  {
1483  nx_file.makeNewGroup(Poco::format(detector_format, group_index), "NXdetector", false);
1484  }
1485  }
1486  nx_file.closeGroup();
1487  for(int k=0; k<crpt->ntrg; ++k)
1488  {
1489  std::string det_name = Poco::format(detector_format, k+1);
1490  std::set<int> spec_set;
1491  int det_tr[10];
1492  for(i=0; i<crpt->ndet; i++)
1493  {
1494  int spec = crpt->spec[i];
1495  int crpt_tr = crpt->timr_crpt[i];
1496  if ( !crpt->isMonitorSpectrum(spec) && (crpt->det_group[i] == 1) && (crpt_tr == k+1) )
1497  {
1498  spec_set.insert(spec);
1499  det_tr[0] = crpt_tr;
1500  }
1501  }
1502  std::vector<int> spec_list;
1503  spec_list.reserve(spec_set.size());
1504  for(std::set<int>::const_iterator it = spec_set.begin(); it != spec_set.end(); ++it)
1505  {
1506  spec_list.push_back(*it);
1507  }
1508  if (spec_list.size() > 0) // this test also used to write NXdata later
1509  {
1510  nx_file.openGroup("instrument", "NXinstrument");
1511  nx_file.openGroup(det_name.c_str(), "NXdetector");
1512  // nx_file.writeData("counts", crpt->raw_data, crpt->nsp1, crpt->ntc1);
1513  ICPTimer time_counts;
1514  int data_size[3] = { crpt->nper_daq, spec_list.size(), crpt->ntc[k] };
1515  nx_file.makeDataSlab("counts", raw_data, data_size, 3);
1516  if ( logs_only && (spec_list.size() > 10) )
1517  {
1518  spec_list.resize(10);
1519  }
1520  std::vector<int> spec_offsets(spec_list.size());
1521  int spec_min = crpt->spec_min[k]; // first spectrum in TR
1522  std::transform(spec_list.begin(), spec_list.end(), spec_offsets.begin(), std::bind2nd(std::minus<int>(), spec_min)); // reset list to base if 0 so arrays allign
1523  int count_dims[3] = { 1, crpt->getNumSpectra(k+1,true), crpt->ntc[k] + 1 };
1524  int slab_start[3] = { 0, 0, 1 };
1525  // int* new_raw_data = makeNewRawData(crpt->raw_data, crpt->nper_daq,
1526  // crpt->nsp1, crpt->ntc1);
1527  // nx_file.writeData("counts", new_raw_data, crpt->nsp1*crpt->nper_daq, crpt->ntc1);
1528  // delete[] new_raw_data;
1529  int slab_size[3] = { 1, spec_list.size(), crpt->ntc[k] };
1530  for(i=0; i<crpt->nper_daq; ++i)
1531  {
1532  int dest_start[3] = { i, 0, 0 };
1533  nx_file.addSlabList("counts", raw_data + crpt->spectrumCRPTOffsetImpl(spec_min, i, raw_data_size), count_dims, 3, dest_start, slab_start, slab_size, spec_offsets);
1534  }
1535  nx_file.writeAttribute("counts", "units", "counts");
1536  nx_file.writeAttribute("counts", "signal", 1);
1537  nx_file.writeAttribute("counts", "axes", "period_index,spectrum_index,time_of_flight");
1538  nx_file.getLink("counts", counts_link);
1539  time_counts.info("writeISISNeXus(counts)", dstatus);
1540  nx_file.writeData("spectrum_index", spec_list);
1541  nx_file.getLink("spectrum_index", spec_link);
1542 
1543  // float* time_array = new float[crpt->ntc1];
1544  // for(i=0; i<crpt->ntc1; i++)
1545  // {
1546  // time_array[i] = (crpt->rtcb1[i+1] + crpt->rtcb1[i]) / 2.0; // microseconds
1547  // }
1548  // nx_file.writeData("time_of_flight", time_array, crpt->ntc1); // centred bins
1549  // delete[] time_array;
1550  nx_file.makeLink(NULL, period_link);
1551  nx_file.makeLink(NULL, tof_links[det_tr[0] - 1]);
1552  nx_file.makeLink(NULL, tof_raw_links[det_tr[0] - 1]);
1553  nx_file.writeData("source_detector_distance", crpt->sdd);
1554  computeDetectorAverage(crpt->tthe, spec_work, det_lookup, spec_list);
1555  nx_file.writeData("polar_angle", spec_work, spec_list.size());
1556  nx_file.writeAttribute("polar_angle", "units", "degree");
1557  computeDetectorAverage(crpt->len2, spec_work, det_lookup, spec_list);
1558  nx_file.writeData("distance", spec_work, spec_list.size());
1559  nx_file.writeAttribute("distance", "units", "metre");
1560  computeDetectorAverage(crpt->delt, spec_work, det_lookup, spec_list);
1561  nx_file.writeData("delt", spec_work, spec_list.size());
1562  for(i=0; i<crpt->nuse; i++)
1563  {
1564  sprintf(buffer, "user_table%02d", i+1);
1565  computeDetectorAverage(&(crpt->ut[i * crpt->ndet]), spec_work, det_lookup, spec_list);
1566  nx_file.writeData(buffer, spec_work, spec_list.size());
1567  if (i == 0)
1568  {
1569  nx_file.writeData("azimuthal_angle", spec_work, spec_list.size()); // same as UT01
1570  nx_file.writeAttribute("azimuthal_angle", "units", "degree");
1571  }
1572  }
1573  nx_file.closeGroup(); // NXdetector
1574  nx_file.closeGroup(); // NXinstrument
1575  if (update)
1576  {
1577  nx_file.openGroup(det_name.c_str(), "NXdata");
1578  }
1579  else
1580  {
1581  nx_file.makeNewGroup(det_name, "NXdata");
1582  }
1583  nx_file.makeLink(NULL, counts_link);
1584  nx_file.makeLink(NULL, tof_links[det_tr[0] - 1]);
1585  nx_file.makeLink(NULL, spec_link);
1586  nx_file.makeLink(NULL, period_link);
1587  nx_file.closeGroup(); // NXdata
1588  time_detector.info("writeISISNeXus(detector)",dstatus);
1589  }
1590  }
1591  delete[] spec_work;
1592  delete[] det_lookup;
1593 
1594  addMonitors(nx_file, crpt, raw_data, raw_data_size, tof_links, period_link, update, dstatus);
1595  if (!update)
1596  {
1597  nx_file.makeNewGroup("runlog","IXrunlog", false);
1598  }
1599 
1600  if ( !update )
1601  {
1602  if (Poco::Util::Application::instance().config().getBool("isisicp.saveeventsinfile", true) )
1603  {
1604  // event mode start - creates detector_events(NXevent_data) and framelog(NXcollection)
1605  NeXusEventWriter nxwriter;
1606  nxwriter.start(crpt, &nx_file, false);
1607  nxwriter.wait();
1608  // event mode finish
1609  // make links to time_of_flight array
1610 // nx_file.openGroup("NXevent_data");
1611 // nx_file.makeLink(NULL, tof_links[det_tr[0] - 1]);
1612  }
1613  else
1614  {
1615  LOGSTR_INFORMATION("events not saved in file - just histograms");
1616  }
1617  }
1618  char* tmp_chars;
1619  ICPTimer time_selogs;
1620  dstatus.addInfoVa(FAC_DAE, "Found %d seblocks", blocks.size());
1621  nx_file.makeNewGroup("selog","IXselog");
1622  for(seblock_map_t::const_iterator it = blocks.begin(); it != blocks.end(); ++it)
1623  {
1624  if (it->first == "ICPEVENT" || it->first == "ICPDEBUG")
1625  {
1626  continue;
1627  }
1628  // dstatus.addInfoVa(FAC_DAE, "Writing block %s", it->first.c_str());
1629  nx_file.makeNewGroup(it->first, "IXseblock");
1630  nx_file.writeData("vi_name", it->second.vi_name);
1631  nx_file.writeData("read_control", it->second.read_control);
1632  nx_file.writeData("set_control", it->second.set_control);
1633  if (it->second.is_real && it->second.fcurrent_value.size() > 0)
1634  {
1635  nx_file.writeData("value", it->second.fcurrent_value);
1636  nx_file.writeAttribute("value", "units", it->second.units);
1637  nx_file.writeData("value_spread", it->second.fcurrent_spread);
1638  nx_file.writeAttribute("value_spread", "units", it->second.units);
1639  nx_file.writeData("setpoint", it->second.fsetpoint_value);
1640  nx_file.writeAttribute("setpoint", "units", it->second.units);
1641  nx_file.writeData("setpoint_spread", it->second.fsetpoint_spread);
1642  nx_file.writeAttribute("setpoint_spread", "units", it->second.units);
1643  }
1644  else if (it->second.current_value.size() > 0)
1645  {
1646  nx_file.writeData("value", it->second.current_value);
1647  nx_file.writeAttribute("value", "units", it->second.units);
1648  nx_file.writeData("setpoint", it->second.setpoint_value);
1649  nx_file.writeAttribute("setpoint", "units", it->second.units);
1650  }
1651  if (it->second.fvalues.size() > 0 || it->second.svalues.size() > 0)
1652  {
1653  nx_file.makeNewGroup("value_log", "NXlog");
1654  nx_file.writeData("name", it->second.nexus_name);
1655  if (it->second.is_real)
1656  {
1657  nx_file.writeData("value", it->second.fvalues);
1658  }
1659  else
1660  {
1661  nx_file.writeData("value", it->second.svalues);
1662  }
1663  nx_file.writeAttribute("value", "units", it->second.units);
1664  nx_file.writeData("time", it->second.time);
1665  nx_file.writeAttribute("time", "units", "second");
1666  nx_file.writeAttribute("time", "start", nx_file.ISOtime(crpt->start_time));
1667  nx_file.closeGroup();
1668  }
1669  nx_file.closeGroup();
1670  }
1671  nx_file.closeGroup();
1672  time_selogs.info("writeISISNeXus(selogs)", dstatus);
1673 
1674 
1675  ICPTimer time_runlogs;
1676  nx_file.openGroup("runlog","IXrunlog");
1677 
1678  RUNBLOCK run_blocks;
1679  if (se_get_run_status(crpt->run_number, crpt->start_time, run_blocks) != 0)
1680  {
1681  dstatus.addInfoVa(FAC_DAE, "SQLITE error %s", se_get_errmsg());
1682  }
1683  nx_file.addLog("good_frames", run_blocks.good_frames, "frames", run_blocks.time, "second", crpt->start_time);
1684  nx_file.addLog("raw_frames", run_blocks.raw_frames, "frames", run_blocks.time, "second", crpt->start_time);
1685  nx_file.addLog("count_rate", run_blocks.count_rate, "counts", run_blocks.time, "second", crpt->start_time);
1686  nx_file.addLog("dae_beam_current", run_blocks.dae_beam_current, "uAh", run_blocks.time, "second", crpt->start_time);
1687  nx_file.addLog("good_uah_log", run_blocks.good_uamps, "uAh", run_blocks.time, "second", crpt->start_time);
1688  nx_file.addLog("is_running", run_blocks.is_running, "none", run_blocks.time, "second", crpt->start_time);
1689  nx_file.addLog("is_waiting", run_blocks.is_waiting, "none", run_blocks.time, "second", crpt->start_time);
1690 
1691  // monitor1_sum and total_counts are now int64_t but Mantid only handles int32_t
1692  std::vector<int> int_vec(run_blocks.monitor1_sum.begin(), run_blocks.monitor1_sum.end());
1693  nx_file.addLog("monitor_sum_1", int_vec, "counts", run_blocks.time, "second", crpt->start_time);
1694  int_vec.assign(run_blocks.total_counts.begin(), run_blocks.total_counts.end());
1695  nx_file.addLog("total_counts", int_vec, "counts", run_blocks.time, "second", crpt->start_time);
1696 // nx_file.addLog("monitor_sum_1", run_blocks.monitor1_sum, "counts", run_blocks.time, "second", crpt->start_time);
1697 // nx_file.addLog("total_counts", run_blocks.total_counts, "counts", run_blocks.time, "second", crpt->start_time);
1698 
1699  nx_file.addLog("np_ratio", run_blocks.np_ratio, "none", run_blocks.time, "second", crpt->start_time);
1700  nx_file.addLog("period", run_blocks.period, "none", run_blocks.time, "second", crpt->start_time);
1701  nx_file.addLog("raw_uah_log", run_blocks.raw_uamps, "uAh", run_blocks.time, "second", crpt->start_time);
1702  nx_file.addLog("run_status", run_blocks.run_status, "none", run_blocks.time, "second", crpt->start_time);
1703  seblock_map_t::const_iterator se_it;
1704  se_it = blocks.find("ICPEVENT");
1705  if (se_it != blocks.end())
1706  {
1707  nx_file.addLog("icp_event", se_it->second.svalues, "", se_it->second.time, "second", crpt->start_time);
1708  }
1709  se_it = blocks.find("ICPDEBUG");
1710  if (se_it != blocks.end())
1711  {
1712  nx_file.addLog("icp_debug", se_it->second.svalues, "", se_it->second.time, "second", crpt->start_time);
1713  }
1714  nx_file.closeGroup();
1715  time_runlogs.info("writeISISNeXus(runlogs)", dstatus);
1716  if (iraw != NULL)
1717  {
1718  ICPTimer time_vms;
1719  nx_file.makeNewGroup("isis_vms_compat", "IXvms");
1720  nx_file.writeData("HDR", (const char*)&(iraw->hdr), sizeof(iraw->hdr) / sizeof(char));
1721  nx_file.writeData("VER1", iraw->frmt_ver_no);
1722  nx_file.writeData("ADD", (const int*)&(iraw->add), sizeof(iraw->add) / sizeof(int));
1723  nx_file.writeData("FORM", iraw->data_format);
1724  nx_file.writeData("VER2", iraw->ver2);
1725  nx_file.writeData("RUN", iraw->r_number);
1726  nx_file.writeData("TITL", iraw->r_title, sizeof(iraw->r_title) / sizeof(char));
1727  nx_file.writeData("USER", (const char*)&(iraw->user), sizeof(iraw->user) / sizeof(char));
1728  nx_file.writeData("IRPB", (const int*)&(iraw->rpb), sizeof(iraw->rpb) / sizeof(int)); // int form of RPB
1729  nx_file.writeData("RRPB", (const float*)&(iraw->rpb), sizeof(iraw->rpb) / sizeof(float)); // real form of RPB
1730  tmp_chars = remove_invalid_chars((const char*)&(iraw->rpb), sizeof(iraw->rpb) / sizeof(char));
1731  nx_file.writeData("CRPB", tmp_chars, sizeof(iraw->rpb) / sizeof(int), sizeof(int)); // char form of RPB
1732  delete[] tmp_chars;
1733  nx_file.writeData("VER3", iraw->ver3);
1734  nx_file.writeData("NAME", iraw->i_inst, sizeof(iraw->i_inst) / sizeof(char));
1735  nx_file.writeData("IVPB", (const int*)&(iraw->ivpb), sizeof(iraw->ivpb) / sizeof(int));
1736  nx_file.writeData("RVPB", (const float*)&(iraw->ivpb), sizeof(iraw->ivpb) / sizeof(float)); //real form of IVPB
1737  nx_file.writeData("NDET", iraw->i_det);
1738  nx_file.writeData("NMON", iraw->i_mon);
1739  nx_file.writeData("NUSE", iraw->i_use);
1740  nx_file.writeData("MDET", iraw->mdet, iraw->i_mon);
1741  nx_file.writeData("MONP", iraw->monp, iraw->i_mon);
1742  // spec, delt, len2, code, tthe, ut are elsewhere
1743  nx_file.writeData("VER4", iraw->ver3);
1744  nx_file.writeData("SPB", (const int*)&(iraw->spb), sizeof(iraw->spb) / sizeof(int)); // int form of SPB
1745  nx_file.writeData("ISPB", (const int*)&(iraw->spb), sizeof(iraw->spb) / sizeof(int)); // int form of SPB
1746  nx_file.writeData("RSPB", (const float*)&(iraw->spb), sizeof(iraw->spb) / sizeof(float)); // real form of SPB
1747  tmp_chars = remove_invalid_chars((const char*)&(iraw->spb), sizeof(iraw->spb) / sizeof(char));
1748  nx_file.writeData("CSPB", tmp_chars, sizeof(iraw->spb) / sizeof(int), sizeof(int)); // char form of SPB
1749  delete[] tmp_chars;
1750  nx_file.writeData("NSEP", 0 /* iraw->e_nse */);
1751  // no e_seblock for now
1752  nx_file.writeData("VER5", iraw->ver5);
1753  nx_file.writeData("DAEP", (const int*)&(iraw->daep), sizeof(iraw->daep) / sizeof(int));
1754  // crat, modn, mpos, timr, udet are elsewhere
1755  nx_file.writeData("VER6", iraw->ver6);
1756  nx_file.writeData("NTRG", iraw->t_ntrg);
1757  nx_file.writeData("NFPP", iraw->t_nfpp);
1758  nx_file.writeData("NPER", iraw->t_nper);
1759  nx_file.writeData("PMAP", iraw->t_pmap, sizeof(iraw->t_pmap) / sizeof(int));
1760  nx_file.writeData("NSP1", iraw->t_nsp1);
1761  nx_file.writeData("NTC1", iraw->t_ntc1);
1762  nx_file.writeData("TCM1", iraw->t_tcm1, sizeof(iraw->t_tcm1) / sizeof(int));
1763  nx_file.writeData("TCP1", (float*)iraw->t_tcp1, sizeof(iraw->t_tcp1) / sizeof(float));
1764  nx_file.writeData("PRE1", iraw->t_pre1);
1765  // t_tcb1 is elsewhere
1766  // nx_file.writeData("TCB1", iraw->t_tcb1, iraw->t_ntc1 + 1);
1767  nx_file.writeData("VER7", iraw->ver7);
1768  nx_file.writeData("ULEN", 0 /* iraw->u_len */);
1769  // no u_dat
1770  nx_file.writeData("VER8", iraw->ver8);
1771  // no dhdr, ddes, dat1, logsect
1772 
1773  nx_file.writeData("VER9", iraw->logsect.ver);
1774  nx_file.writeData("NTNL", iraw->logsect.nlines);
1775  j = 0;
1776  // std::string notes;
1777  for(i=0; i < iraw->logsect.nlines; i++)
1778  {
1779  // notes = notes + iraw->logsect.lines[i].data;
1780  if (iraw->logsect.lines[i].len > j)
1781  {
1782  j = iraw->logsect.lines[i].len;
1783  }
1784  }
1785  nx_file.writeData("NTLL", j);
1786  nx_file.writeData("NOTE", " No notes were made");
1787 
1788  // temporary until in NXdetector
1789  nx_file.writeData("TTHE", crpt->tthe, crpt->ndet);
1790  nx_file.writeData("SPEC", crpt->spec, crpt->ndet);
1791  nx_file.writeData("DELT", crpt->delt, crpt->ndet);
1792  nx_file.writeData("LEN2", crpt->len2, crpt->ndet);
1793  nx_file.writeData("CODE", crpt->code, crpt->ndet);
1794  nx_file.writeData("CRAT", crpt->crat, crpt->ndet);
1795  nx_file.writeData("MODN", crpt->modn, crpt->ndet);
1796  nx_file.writeData("MPOS", crpt->mpos, crpt->ndet);
1797  nx_file.writeData("UDET", crpt->udet, crpt->ndet);
1798  nx_file.writeData("TIMR", crpt->timr_crpt, crpt->ndet);
1799  for(i=0; i<crpt->nuse; i++)
1800  {
1801  sprintf(buffer, "UT%02d", i+1);
1802  nx_file.writeData(buffer, &(crpt->ut[i * crpt->ndet]), crpt->ndet);
1803  }
1804  nx_file.closeGroup();
1805  time_vms.info("writeISISNeXus(vms)", dstatus);
1806  }
1807  nx_file.closeGroup();
1808  nx_file.close();
1809  writeSummaryNeXus(crpt, dstatus);
1810  time_all.info("writeISISNeXus", dstatus);
1811  return 0;
1812 }
1813 
1814 
1815 int NeXusWriter::writeMuonFile(const char* filename, const ISISCRPT_STRUCT* crpt, const isisU32_t* raw_data, isisU32_t raw_data_size, const seblock_map_t& blocks, const Poco::Path& inst_settings_dir, const std::string& inst_xml_file, const std::string& inst_parameter_map_file, DAEstatus& dstatus)
1816 {
1817  ICPTimer time_all;
1818  IXNeXusFile f(nxErrorFunc, (void*)&dstatus);
1820 // set environment variable ISISICP_COMPRESSION to 1 to enable compression of data
1821  if ( (getenv("ISISICP_COMPRESSION") != NULL) &&
1822  !strcmp(getenv("ISISICP_COMPRESSION"), "1") )
1823  {
1824  f.enableCompression();
1825  }
1826  int i, j;
1827  std::string tmp_str;
1828  char buffer[256];
1829  float vector[3] = { 1.0, 1.0, 1.0 };
1830  int int_temp[3] = { 1, 1, 1 };
1831  int persize = crpt->getPeriodSize(); // size of a period
1832  if (f.open(filename, IXNeXusFile::Write, IXNeXusFile::HDF4) != NX_OK)
1833  {
1834  return 0;
1835  }
1837  // user global attribute
1838  f.makeNewGroup("run", "NXentry");
1839  f.writeData("IDF_version", 1); // nexus reader
1840  f.writeData("idf_version", 1); // uda
1841  f.writeData("program_name", "ICP");
1842  f.writeAttribute("program_name", "version", "v1");
1843  f.writeData("number", crpt->run_number);
1844  f.writeData("title", crpt->long_title /*, sizeof(crpt->long_title)*/ );
1845  f.writeData("notes", crpt->comment);
1846  f.writeData("analysis","muonTD");
1847  f.writeData("lab", "ISIS");
1848  f.writeData("beamline", crpt->inst_name /* , sizeof(crpt->inst_name)*/ );
1849  f.writeData("start_time", f.ISOtime(crpt->start_time));
1850  f.writeData("stop_time", f.ISOtime(crpt->stop_time));
1851  sprintf(buffer, "%lu", static_cast<unsigned long>(crpt->duration));
1852  f.writeData("duration", buffer);
1853  f.writeData("switching_states", crpt->nper_daq); // number of periods
1854  f.makeNewGroup("vetos", "IXdae");
1855  for(i=0; i<ISISCRPT_NUM_VETOS; i++)
1856  {
1857  f.writeData(veto_names[i], crpt->vetos[i].frames);
1858  f.writeAttribute(veto_names[i], "enabled", crpt->vetos[i].enabled);
1859  }
1860  f.closeGroup();
1861  f.makeNewGroup("user","NXuser");
1862  f.writeData("name", crpt->user_name);
1863  sprintf(buffer, "%d", crpt->rb_number);
1864  f.writeData("experiment_number", buffer);
1865  f.closeGroup();
1866  f.makeNewGroup("sample","NXSample");
1867  f.writeData("name", crpt->sample_name);
1868  f.writeData("temperature", (float)atof(crpt->temperature_label));
1869  f.writeAttribute("temperature", "units", "Kelvin");
1870  f.writeData("magnetic_field", (float)atof(crpt->field_label));
1871  f.writeAttribute("magnetic_field", "units", "Gauss");
1872  f.writeData("shape",crpt->sample_orientation);
1873  f.writeData("magnetic_field_state", "TF");
1874  f.writeData("magnetic_field_vector", vector, 3);
1875  f.writeAttribute("magnetic_field_vector", "coordinate_system", "cartesian");
1876  f.writeAttribute("magnetic_field_vector", "units", "Gauss");
1877  f.writeAttribute("magnetic_field_vector", "available", 0);
1878  f.writeData("environment", "CCR");
1879  // make link to temperature log
1880  f.closeGroup();
1881  f.makeNewGroup("instrument","NXinstrument");
1882  f.writeData("name", crpt->inst_name /*, sizeof(crpt->inst_name) */);
1883  f.makeNewGroup("detector","NXdetector");
1884  f.writeData("number", crpt->ndet * crpt->nper_daq);
1885  f.writeData("orientation", crpt->instrument_geometry); // "l" or "t"
1886  float* angle_array = new float[4*crpt->ndet*crpt->nper_daq];
1887  memset(angle_array, 0, 4*crpt->ndet*crpt->nper_daq*sizeof(float));
1888  f.writeData("angles", angle_array, 4, crpt->ndet*crpt->nper_daq);
1889  f.writeAttribute("angles", "coordinate_system", "spherical");
1890  f.writeAttribute("angles", "available", 0);
1891  delete []angle_array;
1892  float* deadtimes_array = new float[crpt->ndet*crpt->nper_daq];
1893  int dead_available = readDeadTimes(deadtimes_array, crpt->ndet, Poco::Path(inst_settings_dir, "dtpar.dat").toString().c_str());
1894  for(i=1; i<crpt->nper_daq; i++)
1895  {
1896  for(j=0; j<crpt->ndet; j++)
1897  {
1898  deadtimes_array[i*crpt->ndet+j] = deadtimes_array[j];
1899  }
1900  }
1901  f.writeData("deadtimes", deadtimes_array, crpt->ndet*crpt->nper_daq);
1902  f.writeAttribute("deadtimes", "units", "microseconds");
1903  f.writeAttribute("deadtimes", "available", dead_available);
1904  delete []deadtimes_array;
1905  f.closeGroup();
1906  f.makeNewGroup("collimator", "NXcollimator");
1907  f.writeData("type", "Slits");
1908  f.writeData("aperture", "slit settings");
1909  f.closeGroup();
1910  f.makeNewGroup("beam","NXbeam");
1911  // link to event_log_1
1912  unsigned long sum = 0;
1913  // sum all except spectrum 0
1914  int* period_sum = new int[crpt->nper]; // not nper_daq as we use array later
1915  float* total_counts_period = new float[crpt->nper_daq];
1916  for(j=0; j<crpt->nper_daq; j++)
1917  {
1918  period_sum[j] = 0;
1919  for(i=crpt->ntc[0] + 1; i < persize; i++) // ignore spectrum 0
1920  {
1921  period_sum[j] += raw_data[i+j*persize];
1922  }
1923  sum += period_sum[j];
1924  total_counts_period[j] = (float)period_sum[j] / (float)1e6;
1925  }
1926  f.writeData("total_counts", (float)sum / (float)1e6);
1927  f.writeAttribute("total_counts", "units", "Mev");
1928  f.writeData("total_counts_period", total_counts_period, crpt->nper_daq); // nonstandard
1929  f.writeAttribute("total_counts_period", "units", "Mev"); // nonstandard
1930  delete[] total_counts_period;
1931  f.writeData("daereads", 1);
1932  for(j=0; j<crpt->nper; j++)
1933  {
1934  period_sum[j] = crpt->period[j].good_frames;
1935  }
1936  f.writeData("frames_period", period_sum, crpt->nper); // nonstandard
1937  for(j=0; j<crpt->nper; j++)
1938  {
1939  period_sum[j] = crpt->period[j].total_frames;
1940  }
1941  f.writeData("frames_period_raw", period_sum, crpt->nper); // nonstandard
1942  i=0;
1943  for(j=0; j<crpt->nper; j++)
1944  {
1945  if (crpt->period[j].daq_period >= 0)
1946  {
1947  period_sum[i++] = crpt->period[j].good_frames;
1948  }
1949  }
1950  f.writeData("frames_period_daq", period_sum, crpt->nper_daq); // nonstandard
1951  sum = 0;
1952  for(i=0; i<crpt->nper_daq; i++)
1953  {
1954  sum += period_sum[i];
1955  }
1956  if (crpt->nper == 1) // assume no period card
1957  {
1958  f.writeData("frames", crpt->good_frames);
1959  }
1960  else // assume period card
1961  {
1962  f.writeData("frames", (int)(sum / crpt->nper_daq)); // assumes equal numbers of frames per daq period
1963  }
1964  f.writeData("frames_good", crpt->good_frames); // nonstandard
1965  f.writeData("frames_raw", crpt->total_frames); // nonstandard
1966  f.writeData("period_sequences", crpt->nperseq); // nonstandard
1967  for(j=0; j<crpt->nper; j++)
1968  {
1969  period_sum[j] = crpt->period[j].requested_frames;
1970  }
1971  f.writeData("frames_period_requested", period_sum, crpt->nper); // nonstandard
1972  for(j=0; j<crpt->nper; j++)
1973  {
1974  period_sum[j] = crpt->period[j].type;
1975  }
1976  f.writeData("period_type", period_sum, crpt->nper); // nonstandard
1977  for(j=0; j<crpt->nper; j++)
1978  {
1979  period_sum[j] = crpt->period[j].output;
1980  }
1981  f.writeData("period_output", period_sum, crpt->nper); // nonstandard
1982  tmp_str = crpt->period[0].label;
1983  for(j=1; j<crpt->nper; j++)
1984  {
1985  tmp_str.append(";");
1986  tmp_str.append(crpt->period[j].label);
1987  }
1988  f.writeData("period_labels", tmp_str.c_str()); // nonstandard
1989  delete[] period_sum;
1990  f.closeGroup();
1991  f.closeGroup();
1992  f.makeNewGroup("histogram_data_1", "NXdata");
1993 // f.writeData("counts", crpt->raw_data, crpt->nsp1, crpt->ntc1);
1994  int count_dims[2] = { crpt->nsp[0] + 1, crpt->ntc[0] + 1 };
1995  int slab_dims[2] = { 1, 1 };
1996  int slab_sizes[2] = { crpt->nsp[0], crpt->ntc[0] };
1997  float tzero = 0.0, tzero_offset = 0.0; // microseconds
1998  if (crpt->muon_cerenkov_pulse == 0)
1999  {
2000  readTZero(tzero, tzero_offset, Poco::Path(inst_settings_dir,"basetime_1.uda").toString().c_str());
2001  }
2002  else if (crpt->muon_cerenkov_pulse == 1)
2003  {
2004  readTZero(tzero, tzero_offset, Poco::Path(inst_settings_dir,"basetime_2.uda").toString().c_str());
2005  }
2006  f.writeData("time_zero", tzero);
2007  f.writeAttribute("time_zero", "units", "microseconds");
2008  if (tzero != 0.0)
2009  {
2010  f.writeAttribute("time_zero", "available", 1);
2011  }
2012  else
2013  {
2014  f.writeAttribute("time_zero", "available", 0);
2015  }
2016  int t0_bin = 0;
2017  for(i=0; i < crpt->ntc[0]; i++)
2018  {
2019  if ( (tzero*1000.0 >= crpt->rtcb[0][i]) && (tzero*1000.0 <= crpt->rtcb[0][i+1]) )
2020  {
2021  t0_bin = i + 1;
2022  }
2023  }
2024  float first_good = tzero + tzero_offset;
2025  int first_good_bin = 0;
2026  for(i=0; i < crpt->ntc[0]; i++)
2027  {
2028  if ( (first_good*1000.0 >= crpt->rtcb[0][i]) && (first_good*1000.0 <= crpt->rtcb[0][i+1]) )
2029  {
2030  first_good_bin = i + 1;
2031  }
2032  }
2033  int* new_raw_data = makeNewRawData(raw_data, crpt->nper_daq,
2034  crpt->nsp[0], crpt->ntc[0]);
2035  f.writeData("counts", new_raw_data, crpt->nsp[0] * crpt->nper_daq, crpt->ntc[0]);
2036  delete[] new_raw_data;
2037 // f.writeSlab("counts", crpt->raw_data, count_dims, 2, slab_dims, slab_sizes);
2038  f.writeAttribute("counts", "units", "counts");
2039  f.writeAttribute("counts", "signal", 1);
2040  f.writeAttribute("counts", "number", crpt->nsp[0] * crpt->nper_daq);
2041  f.writeAttribute("counts", "length", crpt->ntc[0]);
2042  f.writeAttribute("counts", "t0_bin", t0_bin);
2043  f.writeAttribute("counts", "first_good_bin", first_good_bin);
2044  f.writeAttribute("counts", "last_good_bin", crpt->ntc[0]);
2045  f.writeAttribute("counts", "offset", (float)(1000.0* (crpt->rtcb[0][1] - crpt->rtcb[0][0]) / 2.0));
2046  // unclear whther resolution is int or real
2047  f.writeData("resolution", (int)(1000.0* (crpt->rtcb[0][1] - crpt->rtcb[0][0])));
2048  f.writeAttribute("resolution", "units", "picoseconds");
2049  float* time_array = new float[crpt->ntc[0]];
2050  for(i=0; i<crpt->ntc[0]; i++)
2051  {
2052  time_array[i] = (crpt->rtcb[0][i+1] + crpt->rtcb[0][i]) / (2.0 * 1000.0); // microseconds
2053  }
2054  f.writeData("raw_time", time_array, crpt->ntc[0]);
2055  f.writeAttribute("raw_time", "axis", 1);
2056  f.writeAttribute("raw_time", "primary", 1);
2057  f.writeAttribute("raw_time", "units", "microseconds");
2058  for(i=0; i<crpt->ntc[0]; i++)
2059  {
2060  time_array[i] -= tzero;
2061  }
2062  f.writeData("corrected_time", time_array, crpt->ntc[0]);
2063  f.writeAttribute("corrected_time", "axis", 1);
2064  f.writeAttribute("corrected_time", "units", "microseconds");
2065  delete[] time_array;
2066  int* grouping = new int[crpt->ndet * crpt->nper_daq];
2067  int ngroup = 1;
2068  std::string file_prefix;
2069  if ( (crpt->instrument_geometry[0] == 'l') || (crpt->instrument_geometry[0] == 'L') )
2070  {
2071  file_prefix = "long";
2072  }
2073  else
2074  {
2075  file_prefix = "trans";
2076  }
2077  Poco::Path search_expr(inst_settings_dir, (file_prefix+"*.uda").c_str()); // poco glob is shell like not RE like
2078  std::set<std::string> files_list;
2079  Poco::Glob::glob(search_expr, files_list, Poco::Glob::GLOB_CASELESS);
2080  Poco::RegularExpression re(file_prefix+"(.*)\\.uda", Poco::RegularExpression::RE_CASELESS);
2081  Poco::RegularExpression::MatchVec matches;
2082  BOOST_FOREACH(const std::string& file, files_list)
2083  {
2084  re.match(file, 0, matches);
2085  if (matches.size() == 2)
2086  {
2087  ngroup = readGrouping(grouping, crpt->ndet, Poco::Path(inst_settings_dir,file.c_str()).toString().c_str());
2088  for(i=1; i<crpt->nper_daq; i++)
2089  {
2090  for(j=0; j<crpt->ndet; j++)
2091  {
2092  grouping[i*crpt->ndet+j] = grouping[j];
2093  }
2094  }
2095  std::string grouping_name = "grouping" + file.substr(matches[1].offset, matches[1].length);
2096  std::replace(grouping_name.begin(), grouping_name.end(), ' ', '_');
2097  f.writeData(grouping_name.c_str(), grouping, crpt->ndet * crpt->nper_daq);
2098  f.writeAttribute(grouping_name.c_str(), "available", 1);
2099  if (matches[1].length == 0)
2100  {
2101  f.writeAttribute(grouping_name.c_str(), "primary", 1);
2102  }
2103  }
2104  }
2105  float* alpha_array = new float[ngroup*ngroup];
2106  for(i=0; i<ngroup*ngroup; i++)
2107  {
2108  alpha_array[i] = 1.0;
2109  }
2110  f.writeData("alpha", alpha_array, ngroup*ngroup);
2111  f.writeAttribute("alpha", "available", 0);
2112  delete[] grouping;
2113  delete[] alpha_array;
2114  f.closeGroup();
2115 
2116  ICPTimer time_selogs;
2117  std::string log_name;
2118  dstatus.addInfoVa(FAC_DAE, "Found %d seblocks", blocks.size());
2119  for(seblock_map_t::const_iterator it = blocks.begin(); it != blocks.end(); ++it)
2120  {
2121  if (it->first == "ICPEVENT")
2122  {
2123  log_name = "ICPevent";
2124  }
2125  else if (strcmp(it->first.c_str(), "Temp_Sample") == 0)
2126  {
2127  log_name = "temperature_log_1";
2128  }
2129  else
2130  {
2131  log_name = it->first;
2132  }
2133  // dstatus.addInfoVa(FAC_DAE, "Writing block %s", it->first.c_str());
2134  if (it->second.fvalues.size() > 0 || it->second.svalues.size() > 0)
2135  {
2136  f.makeNewGroup(log_name, "NXlog");
2137  f.writeData("name", it->first);
2138  if (it->second.is_real)
2139  {
2140  f.writeAttribute("name", "available", (int)it->second.fvalues.size());
2141  f.writeData("values", it->second.fvalues); // this should really be "value", but leave for backward compatability of muon v1
2142  }
2143  else
2144  {
2145  f.writeAttribute("name", "available", (int)it->second.svalues.size());
2146  f.writeData("values", it->second.svalues);
2147  }
2148  f.writeAttribute("values", "units", (it->second.units.size() > 0 ? it->second.units.c_str() : "K") );
2149  f.writeData("time", it->second.time);
2150  f.writeAttribute("time", "units", "seconds");
2151  f.writeAttribute("time", "start", f.ISOtime(crpt->start_time));
2152  f.closeGroup();
2153  }
2154  }
2155  time_selogs.info("writeMuonFile(selogs)", dstatus);
2156 
2157 #if 0
2158  // musr00000000_block_name.txt
2159  std::string block_name;
2160  std::vector<std::string> file_list;
2161  sprintf(buffer, "%s%0*d_*.txt", crpt->inst_name, run_number_digits, crpt->run_number);
2162 // sprintf(buffer, "%s%d_*.txt", crpt->inst_name, crpt->run_number);
2163  findFiles("c:\\data", buffer, file_list);
2164  for(i=0; i<file_list.size(); i++)
2165  {
2166  j = file_list[i].find_last_of("\\"); // block name starts after first _
2167  j = file_list[i].find_first_of("_",j); // block name starts after first _
2168  k = file_list[i].length() - (j + 1) - 4; // length of block name
2169  block_name = file_list[i].substr(j+1, k);
2170  if (strcmp(block_name.c_str(), "Temp_Sample") == 0)
2171  {
2172  strcpy(buffer, "temperature_log_1");
2173  }
2174  else
2175  {
2176  strcpy(buffer, block_name.c_str());
2177  }
2178  f.addLog(buffer, file_list[i].c_str(), block_name.c_str(),
2179  "K", crpt->start_time);
2180  }
2181 #endif
2182 
2183  f.makeNewGroup("event_log_1", "NXlog");
2184  f.writeData("name", "ISIS beam");
2185  f.writeAttribute("name", "available", 0); // number of values
2186  f.writeData("values", vector, 3);
2187  f.writeAttribute("values", "units", "counts");
2188  f.writeData("time", vector, 3);
2189  f.writeAttribute("time", "units", "seconds");
2190  f.closeGroup();
2191  f.closeGroup();
2192  f.close();
2193  time_all.info("writeMuonFile v1", dstatus);
2194  if (Poco::Util::Application::instance().config().getBool("isisicp.muon.nexusv2test", false))
2195  {
2196  std::string filename_v2(filename);
2197  filename_v2.append("_v2");
2198  writeISISNeXus(filename_v2.c_str(), false, crpt, raw_data, raw_data_size, NULL, blocks, inst_xml_file, inst_parameter_map_file, dstatus);
2199  time_all.info("writeMuonFile v1+v2", dstatus);
2200  }
2201  return 0;
2202 }
2203 
2204 // add log files when SECI has not been set to log to database
2205 // ICPEVENT does not need to be added as ICP already did that from database
2206 int NeXusWriter::addMissingMuonLogs(const char* filename, const char* logs_path, const char* new_comment,
2207  const char* new_sample_name, DAEstatus& dstatus)
2208 {
2209  ICPTimer time_all;
2210  IXNeXusFile f(nxErrorFunc, (void*)&dstatus);
2212 // set environment variable ISISICP_COMPRESSION to 1 to enable compression of data
2213  if ( (getenv("ISISICP_COMPRESSION") != NULL) &&
2214  !strcmp(getenv("ISISICP_COMPRESSION"), "1") )
2215  {
2216  f.enableCompression();
2217  }
2218  int i, j, k;
2219  int run_number_digits = 8;
2220  int run_number;
2221  time_t start_time;
2222  std::string sample_name, inst_name, long_title, comment, start_time_iso;
2223  std::string tmp_str;
2224  float magnetic_field, temperature;
2225  char buffer[512];
2226  if (f.open(filename, IXNeXusFile::Update) != NX_OK)
2227  {
2228  return 0;
2229  }
2230  // user global attribute
2231  f.openGroup("run", "NXentry");
2232  f.readData("number", run_number);
2233  f.readData("start_time", start_time_iso);
2234  start_time = f.unixTime(start_time_iso.c_str());
2235  if (new_comment != NULL)
2236  {
2237  comment = new_comment;
2238  f.writeData("notes", comment);
2239  }
2240  else
2241  {
2242  f.readData("notes", comment);
2243  }
2244  f.readData("beamline", inst_name);
2245  f.openGroup("sample","NXSample");
2246  if (new_sample_name != NULL)
2247  {
2248  sample_name = new_sample_name;
2249  f.writeData("name", sample_name);
2250  }
2251  else
2252  {
2253  f.readData("name", sample_name);
2254  }
2255  f.readData("temperature", temperature);
2256  f.readData("magnetic_field", magnetic_field);
2257  f.closeGroup();
2258  if (new_sample_name != NULL)
2259  {
2260  sprintf(buffer, "%s T=%f F=%f", sample_name.c_str(), temperature, magnetic_field);
2261  long_title = buffer;
2262  f.writeData("title", long_title);
2263  }
2264  else
2265  {
2266  f.readData("title", long_title);
2267  }
2268  // musr00000000_block_name.txt
2269  std::string block_name;
2270  std::vector<std::string> file_list;
2271  sprintf(buffer, "%s%0*d_*.txt", inst_name.c_str(), run_number_digits, run_number);
2272 // sprintf(buffer, "%s%d_*.txt", crpt->inst_name, crpt->run_number);
2273  findFiles(logs_path, buffer, file_list);
2274  for(i=0; i<file_list.size(); i++)
2275  {
2276  j = file_list[i].find_last_of("\\"); // block name starts after first _
2277  j = file_list[i].find_first_of("_",j); // block name starts after first _
2278  k = file_list[i].length() - (j + 1) - 4; // length of block name
2279  block_name = file_list[i].substr(j+1, k);
2280  if (stricmp(block_name.c_str(), "ICPEVENT") == 0) // already done by ICP
2281  {
2282  continue;
2283  }
2284  else if (strcmp(block_name.c_str(), "Temp_Sample") == 0)
2285  {
2286  strcpy(buffer, "temperature_log_1");
2287  }
2288  else
2289  {
2290  strcpy(buffer, block_name.c_str());
2291  }
2292  f.addLog(buffer, file_list[i].c_str(), block_name.c_str(),
2293  "K", start_time);
2294  }
2295  f.closeGroup();
2296  f.close();
2297  time_all.info("updateMuonFile v1", dstatus);
2298  return 0;
2299 }
2300 
2301 
2302 // ISO time of form "2004-11-10T17:04:54"
2303 // return -1 on error
2304 time_t IXNeXusFile::unixTime(const char* isotime)
2305 {
2306  int n;
2307  struct tm tm_struct;
2308  if (strlen(isotime) < 19)
2309  {
2310  return (time_t)-1;
2311  }
2312  n = sscanf(isotime, "%d-%d-%dT%d:%d:%d",
2313  &tm_struct.tm_year, &tm_struct.tm_mon, &tm_struct.tm_mday,
2314  &tm_struct.tm_hour, &tm_struct.tm_min, &tm_struct.tm_sec);
2315 
2316  if (n != 6) // enginx had " " rather than "T" separating the bits
2317  {
2318  n = sscanf(isotime, "%d-%d-%d %d:%d:%d",
2319  &tm_struct.tm_year, &tm_struct.tm_mon, &tm_struct.tm_mday,
2320  &tm_struct.tm_hour, &tm_struct.tm_min, &tm_struct.tm_sec);
2321  }
2322  if (n != 6)
2323  {
2324  return (time_t)-1;
2325  }
2326  tm_struct.tm_year -= 1900; // year field is 1900 based
2327  tm_struct.tm_mon -= 1; // January is 0 not 1 in this structure
2328  tm_struct.tm_isdst = -1; // status of DST is unknown - CRT will decide
2329  return mktime(&tm_struct);
2330 }
2331 
2332 // log file entries of form "2004-11-10T17:04:54 0.0"
2333 // if ref_time is 0, use first time in log file
2334 int IXNeXusFile::addLog(const char* nxname, const char* filename,
2335  const char* log_name, const char* log_units, time_t ref_time)
2336 {
2337  HANDLE h = INVALID_HANDLE_VALUE;
2338  int ntries = 3;
2339  while((ntries >= 0) && (h == INVALID_HANDLE_VALUE))
2340  {
2341  h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2342  defaultNoInheritHandles(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2343  if (h == INVALID_HANDLE_VALUE)
2344  {
2345  Sleep(500);
2346  --ntries;
2347  }
2348  }
2349  if (h == INVALID_HANDLE_VALUE)
2350  {
2351  return 0;
2352  }
2353  DWORD nbuffer = GetFileSize(h, NULL);
2354  if ( nbuffer == INVALID_FILE_SIZE || nbuffer > (100 * 1000000) )
2355  {
2356  CloseHandle(h);
2357  return 0;
2358  }
2359  char* buffer = new char[nbuffer+1];
2360  if (buffer == NULL)
2361  {
2362  CloseHandle(h);
2363  return 0;
2364  }
2365  DWORD nread = 0;
2366  if (ReadFile(h, buffer, nbuffer, &nread, NULL) == 0)
2367  {
2368  delete[] buffer;
2369  CloseHandle(h);
2370  return 0;
2371  }
2372  CloseHandle(h);
2373  buffer[nread] = '\0';
2374  buffer[nbuffer] = '\0';
2375  std::string s(buffer);
2376  std::istringstream iss(s);
2377  delete[] buffer;
2378  float *times = 0, *values = 0;
2379  // work out how many lines
2380  int n = 0;
2381  while((void*)iss != 0)
2382  {
2383  getline(iss, s);
2384  if ((void*)iss != 0)
2385  {
2386  n++;
2387  }
2388  }
2389  if (n == 0)
2390  {
2391  return 0;
2392  }
2393  times = new float[n];
2394  values = new float[n];
2395  // now read file proper
2396  iss.clear();
2397  iss.seekg(std::ios::beg);
2398  getline(iss, s);
2399  if (s.length() < 20)
2400  {
2401  return 0;
2402  }
2403  if (ref_time == 0)
2404  {
2405  ref_time = unixTime(s.substr(0,19).c_str());
2406  }
2407  n = 0;
2408  times[n] = difftime(unixTime(s.substr(0,19).c_str()), ref_time);
2409  values[n] = atof(s.substr(19,1000).c_str());
2410  n++;
2411  while((void*)iss != 0)
2412  {
2413  getline(iss, s);
2414  if ((void*)iss != 0)
2415  {
2416  if (s.length() > 19)
2417  {
2418  times[n] = difftime(unixTime(s.substr(0,19).c_str()), ref_time);
2419  values[n] = atof(s.substr(19,1000).c_str());
2420  }
2421  else
2422  {
2423  times[n] = 0;
2424  values[n] = 0.0;
2425  }
2426  n++;
2427  }
2428  }
2429 
2430  makeNewGroup(nxname, "NXlog");
2431  writeData("name", log_name);
2432  writeAttribute("name", "available", n);
2433  writeData("values", values, n); // this should really be "value", but leave for backward compatability of muon v1
2434  writeAttribute("values", "units", log_units);
2435  writeData("time", times, n);
2436  writeAttribute("time", "units", "second");
2437  closeGroup();
2438  delete[] times;
2439  delete[] values;
2440  return 0;
2441 }
2442 
2443 template<typename T>
2444 int IXNeXusFile::addLog(const char* nxname, const std::vector<T>& values, const char* value_units,
2445  const std::vector<float>& time, const char* time_units, time_t ref_time)
2446 {
2447  if (values.size() > 0)
2448  {
2449  makeNewGroup(nxname, "NXlog");
2450  writeData("value", values);
2451  writeAttribute("value", "units", value_units);
2452  writeData("time", time);
2453  writeAttribute("time", "start", ISOtime(ref_time));
2454  writeAttribute("time", "units", time_units);
2455  closeGroup();
2456  }
2457  return 0;
2458 }
2459 
2460 int IXNeXusFile::readData(const char* data_name, std::string& value)
2461 {
2462  int n, rank, dims[20], data_type;
2463  char* char_data;
2464  if (NXopendata(m_fileid, data_name) == NX_OK)
2465  {
2466  NXgetinfo(m_fileid, &rank, dims, &data_type);
2467  if (rank == 1 && data_type == NX_CHAR)
2468  {
2469  n = dims[0];
2470  char_data = new char[n + 1];
2471  NXgetdata(m_fileid, char_data);
2472  char_data[n] = '\0';
2473  value = char_data;
2474  }
2475  else
2476  {
2477  value = "";
2478  }
2479  NXclosedata(m_fileid);
2480  return IXNeXusFile::OK;
2481  }
2482  else
2483  {
2484  return IXNeXusFile::Error;
2485  }
2486 }
2487 
2488 int IXNeXusFile::readData(const char* data_name, int& value)
2489 {
2490  int rank, dims[20], data_type;
2491  if (NXopendata(m_fileid, data_name) == NX_OK)
2492  {
2493  NXgetinfo(m_fileid, &rank, dims, &data_type);
2494  if (rank == 1 && data_type == NX_INT32 && dims[0] == 1)
2495  {
2496  NXgetdata(m_fileid, &value);
2497  }
2498  else
2499  {
2500  value = 0;
2501  }
2502  NXclosedata(m_fileid);
2503  return IXNeXusFile::OK;
2504  }
2505  else
2506  {
2507  return IXNeXusFile::Error;
2508  }
2509 }
2510 
2511 int IXNeXusFile::readData(const char* data_name, float& value)
2512 {
2513  int rank, dims[20], data_type;
2514  if (NXopendata(m_fileid, data_name) == NX_OK)
2515  {
2516  NXgetinfo(m_fileid, &rank, dims, &data_type);
2517  if (rank == 1 && data_type == NX_FLOAT32 && dims[0] == 1)
2518  {
2519  NXgetdata(m_fileid, &value);
2520  }
2521  else
2522  {
2523  value = 0;
2524  }
2525  NXclosedata(m_fileid);
2526  return IXNeXusFile::OK;
2527  }
2528  else
2529  {
2530  return IXNeXusFile::Error;
2531  }
2532 }
2533 
2534 
2535 
2536 int IXNeXusFile::listEntries(std::list<std::string>& entries, bool groups_only)
2537 {
2538  char entry_name[100], entry_class[100];
2539  int data_type;
2540  entries.clear();
2541  NXinitgroupdir(m_fileid);
2542  while(NXgetnextentry(m_fileid, entry_name, entry_class, &data_type) == NX_OK)
2543  {
2544  if ( groups_only && ((strlen(entry_class) == 0) || !strcmp(entry_class, "SDS")) )
2545  {
2546  ;
2547  }
2548  else
2549  {
2550  entries.push_back(entry_name);
2551  }
2552  }
2553  return IXNeXusFile::OK;
2554 }
2555 
2556 int IXNeXusFile::openGroup(const char* group_name, const char* group_class)
2557 {
2558  return NXopengroup(m_fileid, group_name, (char*)group_class);
2559 }
2560 
2561 // we want to write a portion of an array to the file
2562 // the passed array is of size (dims_array[ndims]) but we only
2563 // want to write a slab of it
2564 // only for ndims = 1 or 2 at moment
2565 int IXNeXusFile::makeData(const char* data_name, int nxtype, const int* dims_array, int ndims)
2566 {
2567  NXstatus ret;
2568  int len = 1;
2569  int dummy_dims_array[1] = { 1 };
2570  int* chunk_size = new int[ndims];
2571  for(int i=0; i<ndims; i++)
2572  {
2573  len *= dims_array[i];
2574  }
2575  if (len == 0)
2576  {
2577  delete []chunk_size;
2578  return NXmakedata(m_fileid, data_name, nxtype, ndims, (int*)dims_array);
2579  }
2580  // we want only the final array dimension to be compressed
2581  for(int i=0; i<ndims; i++)
2582  {
2583  chunk_size[i] = 1;
2584  }
2585  chunk_size[ndims-1] = dims_array[ndims-1];
2586  if ((m_compression_type != NX_COMP_NONE) && (chunk_size[ndims-1] > MIN_COMP_LEN) )
2587  {
2588  ret = NXcompmakedata(m_fileid, data_name, nxtype, ndims, (int*)dims_array, m_compression_type, chunk_size);
2589  }
2590  else
2591  {
2592  ret = NXmakedata(m_fileid, data_name, nxtype, ndims, (int*)dims_array);
2593  }
2594  delete []chunk_size;
2595  return ret;
2596 }
2597 
2598 int IXNeXusFile::makeDataChunked(const char* data_name, int nxtype, const int* dims_array, const int* chunk_size, int ndims)
2599 {
2600  return NXcompmakedata(m_fileid, data_name, nxtype, ndims, (int*)dims_array, m_compression_type, (int*)chunk_size);
2601 }
2602 
2603 template int IXNeXusFile::addLog(const char* nxname, const std::vector<uint32_t>& values, const char* value_units,
2604  const std::vector<float>& time, const char* time_units, time_t ref_time);
int t_ntrg
Definition: isisraw.h:297
int m_spectra_chunk
Definition: nexuswriter.h:20
NXhandle fileid()
Definition: nexuswriter.h:174
virtual void wait()
int openGroup(const char *group_name, const char *group_class)
nx_error_t m_error_func
Definition: nexuswriter.h:21
static int addSlabList(NXhandle fileid, const char *data_name, const T *value, const int *dims_array, int ndims, int dest_start[], const int *slab_start, const int *slab_size, const std::vector< int > &slab_list, bool convert_null, int compression_type, int spectra_chunk)
USER_STRUCT user
Definition: isisraw.h:263
void setErrorReporter(nx_error_t error_func, void *error_arg)
char comment[512]
Definition: isiscrpt.h:400
#define FAC_DAE
char sample_geometry[80]
Definition: isiscrpt.h:416
const char * ISOtime(time_t time)
#define ERRTYPE_OUTOFMEM
int timr_crpt[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:313
void start(const ISISCRPT_STRUCT *crpt, IXNeXusFile *file, bool create_empty)
int listEntries(std::list< std::string > &entries, bool groups_only=false)
static int writeSlab(NXhandle fileid, const char *data_name, const T *value, const int *dims_array, int ndims, const int *slab_start, const int *slab_size, bool convert_null, int compression_type)
int getPeriodSize() const
Definition: isiscrpt.h:658
int getNumSpectra(bool include_spectrum_zero=false) const
Definition: isiscrpt.cpp:926
int code[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:304
int readData(const char *data_name, std::string &value)
int addVa(int facility, int severity, int errtype, const char *format,...)
Definition: DAEstatus.cpp:54
int udet[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:315
static int writeAttribute(NXhandle fileid, const char *data_name, const char *attr_name, const T *value, int len, bool convert_null)
Definition: nexuswriter.cpp:79
std::vector< int > raw_frames
Definition: selogger.h:109
IXNeXusFile * clone()
int * monp
Definition: isisraw.h:274
static int readTZero(float &tzero, float &tzero_offset, const char *file)
std::vector< int64_t > total_counts
Definition: selogger.h:114
int monitorNumberToSpectrum(int monitor_number) const
monitor numbers start at 1, indexes in mdet also start at 1 for historical (i.e fortran and old raw f...
Definition: isiscrpt.h:577
std::vector< float > count_rate
Definition: selogger.h:115
float rtcb[ISISCRPT_MAX_NTRG][ISISCRPT_MAX_TIMECHANB]
Definition: isiscrpt.h:344
int ver5
Definition: isisraw.h:287
int t_tcm1[5]
Definition: isisraw.h:303
int open(const char *filename, int mode, int type=IXNeXusFile::HDF5)
char field_label[256]
Definition: isiscrpt.h:398
int modn[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:308
int t_pre1
Definition: isisraw.h:305
SELOGGER_API int __stdcall se_get_run_status(int run_number, time_t ref_time, RUNBLOCK &blocks)
Definition: selogger.cpp:1248
float sample_thickness
Definition: isiscrpt.h:412
float sample_height
Definition: isiscrpt.h:411
int ver3
Definition: isisraw.h:266
int clone(const IXNeXusFile &orig)
RUNTABLE wiring_table
Definition: isiscrpt.h:274
int makeNewGroup(const char *name, const char *nxclass, bool open_group=true)
int frmt_ver_no
Definition: isisraw.h:256
#define ISISCRPT_MAX_NTRG
Definition: isiscrpt.h:20
uint32_t spectrumCRPTOffsetImpl(int spec, int daq_period) const
Definition: isiscrpt.h:624
static time_t unixTime(const char *isotime)
Definition: selogger.cpp:153
time_t start_time
Definition: isiscrpt.h:254
int t_pmap[256]
Definition: isisraw.h:300
int makeData(const char *data_name, int nxtype, const int *dims_array, int ndims)
static const char * veto_names[]
these names will be used in the NeXus data file, so no spaces and lowercase only
Definition: isiscrpt.h:106
float sample_width
Definition: isiscrpt.h:410
unsigned long isisU32_t
Definition: isisvme_types.h:8
int writeSlabList(const char *data_name, const unsigned long *value, const int *dims_array, int ndims, const int *slab_start, const int *slab_size, const std::vector< int > &slab_list)
float t_tcp1[5][4]
Definition: isisraw.h:304
static int writeData(NXhandle fileid, const char *data_name, const T *value, const int *dims_array, int ndims, bool convert_null, int compression_type)
std::map< std::string, SEBLOCK > seblock_map_t
Definition: selogger.h:128
RUNTABLE spectra_table
Definition: isiscrpt.h:275
SECURITY_ATTRIBUTES * defaultNoInheritHandles()
Definition: icputils.cpp:1121
int addLog(const char *nxname, const char *filename, const char *log_name, const char *log_units, time_t ref_time)
int mpos[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:309
float total_uamph
Definition: isiscrpt.h:281
unsigned good_frames
Definition: isiscrpt.h:278
std::vector< float > raw_uamps
Definition: selogger.h:111
std::vector< float > good_uamps
Definition: selogger.h:110
char instrument_xml_file[ISISCRPT_MAX_FNAMELEN]
Definition: isiscrpt.h:445
NXhandle m_fileid
Definition: nexuswriter.h:17
time_t unixTime(const char *isotime)
const char * detector_format
int compression_block_size
Definition: isiscrpt.h:481
static int ISOtime(time_t time, char *buffer, int len)
Definition: selogger.cpp:181
static int writeSlabList(NXhandle fileid, const char *data_name, const T *value, const int *dims_array, int ndims, const int *slab_start, const int *slab_size, const std::vector< int > &slab_list, bool convert_null, int compression_type, int spectra_chunk)
int makeDataSlab(const char *data_name, const unsigned long *value, const int *dims_array, int ndims)
SELOGGER_API const char *__stdcall se_get_errmsg()
Definition: selogger.cpp:696
int makeDataChunked(const char *data_name, int nxtype, const int *dims_array, const int *chunk_array, int ndims)
int addMissingMuonLogs(const char *filename, const char *logs_path, const char *new_comment, const char *new_sample_name, DAEstatus &dstatus)
boost::array< int, ISISCRPT_MAX_NTRG > spec_min
range of spectrum numbers in CRPT time regime
Definition: isiscrpt.h:335
float tthe[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:305
static void nxErrorFunc(void *arg, char *text)
boost::array< VETO, ISISCRPT_NUM_VETOS > vetos
Definition: isiscrpt.h:360
int i_use
Definition: isisraw.h:271
int closeGroup()
char institute[ISISCRPT_INSTITUTE_NAME_LEN+1]
Definition: isiscrpt.h:354
static const T * nullValue(const T *, int NXTYPE)
Definition: nexuswriter.cpp:53
std::vector< float > np_ratio
Definition: selogger.h:116
#define FAC_CRPT
char temperature_label[256]
Definition: isiscrpt.h:399
std::vector< float > time
Definition: selogger.h:103
float delt[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:302
int ver
Definition: isisraw.h:232
int writeSlab(const char *data_name, const int *value, const int *dims_array, int ndims, const int *slab_start, const int *slab_size)
void * m_error_arg
Definition: nexuswriter.h:22
#define ISISCRPT_NUM_VETOS
max number of vetos
Definition: isiscrpt.h:112
#define SEV_ERROR
char i_inst[8]
Definition: isisraw.h:267
int dae_type
time CRPT unloaded (may not be set if program crashed)
Definition: isiscrpt.h:247
int t_nper
Definition: isisraw.h:299
int writeAttribute(const std::string &data_name, const std::string &attr_name, const std::string &value)
Definition: nexuswriter.h:103
char long_title[ISISCRPT_TITLE_LEN+1]
Definition: isiscrpt.h:350
char measurement_id[ICP_NAME_LEN]
Definition: isiscrpt.h:437
int findFiles(const char *directory, const char *pattern, std::vector< std::string > &list, bool full_path)
Definition: icputils.cpp:477
int r_number
Definition: isisraw.h:261
static void computeDetectorAverage(const float *det_vals, float *spec_vals, const std::vector< int > *det_lookup, const std::vector< int > &spec_list)
std::vector< int > period
Definition: selogger.h:104
static char * remove_invalid_chars(const char *str, int len)
Definition: nexuswriter.cpp:32
int ver7
Definition: isisraw.h:309
time_t stop_time
Definition: isiscrpt.h:256
void setSpectraChunkSize(int nsp)
Definition: nexuswriter.h:164
int i_det
Definition: isisraw.h:269
SELOGGER_API int __stdcall se_get_measurement_label(const char *measurement_id, std::string &res)
Definition: selogger.cpp:905
RUNTABLE detector_table
Definition: isiscrpt.h:273
static void readExternalFile(const std::string &file_name, std::string &file_contents)
#define LOGSTR_INFORMATION(__arg)
Definition: IsisBase.h:78
void(* nx_error_t)(void *arg, char *text)
Definition: nexuswriter.h:4
int tcb[ISISCRPT_MAX_NTRG][ISISCRPT_MAX_TIMECHANB]
Definition: isiscrpt.h:343
int enableOptions(Options options)
Definition: nexuswriter.h:163
#define LOGSTR_ERROR(__arg)
Definition: IsisBase.h:99
LOG_LINE * lines
Definition: isisraw.h:234
int spec[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:301
int data_format
Definition: isisraw.h:258
unsigned total_frames
Definition: isiscrpt.h:279
char fname[ISISCRPT_MAX_FNAMELEN]
Definition: isiscrpt.h:81
double info(const char *title, std::ostream &os, bool add_nl=true)
Definition: icptimer.h:83
bool isMonitorSpectrum(int spec) const
Definition: isiscrpt.h:619
int spectrumGroup(int spec) const
Definition: isiscrpt.h:815
int addWarningVa(int facility, const char *format,...)
Definition: DAEstatus.cpp:106
int writeMuonFile(const char *filename, const ISISCRPT_STRUCT *crpt, const isisU32_t *raw_data, isisU32_t raw_data_size, const seblock_map_t &blocks, const Poco::Path &inst_settings_dir, const std::string &inst_xml_file, const std::string &inst_parameter_map_file, DAEstatus &dstatus)
boost::array< int, ISISCRPT_MAX_MONITOR > mdet
Definition: isiscrpt.h:295
static int * makeNewRawData(const isisU32_t *raw_data, int nper_daq, int nsp1, int ntc1)
only used by muons and hence OK for it only to work for one TR
Definition: nexuswriter.cpp:12
const char * detector_base
char isis_cycle[ISISCRPT_MAX_LVXML_SIZE]
Definition: isiscrpt.h:444
int t_nsp1
Definition: isisraw.h:301
int getLink(const char *name, const char *nxclass, NXlink &link)
int writeISISNeXus(const char *filename, bool logs_only, const ISISCRPT_STRUCT *crpt, const isisU32_t *raw_data, isisU32_t raw_data_size, const ISISRAW *iraw, const seblock_map_t &blocks, const std::string &inst_xml_file, const std::string &inst_parameter_map_file, DAEstatus &dstatus, bool update=false)
char sample_name[256]
Definition: isiscrpt.h:397
SELOGGER_API int __stdcall se_get_seci_config(std::string &seci_config)
Definition: selogger.cpp:739
static int writeSummaryNeXus(const ISISCRPT_STRUCT *crpt, DAEstatus &dstatus)
float good_uamph
Definition: isiscrpt.h:280
std::vector< float > dae_beam_current
Definition: selogger.h:113
int i_mon
Definition: isisraw.h:270
int spectrumCRPTTR(int spec) const
Definition: isiscrpt.h:794
static int addSlab(NXhandle fileid, const T *value, const int64_t *dims_array, int ndims, const int64_t *slab_start, const int64_t *slab_size, const int64_t *dest_start, int compression_type)
RPB_STRUCT rpb
Definition: isisraw.h:264
LOG_STRUCT logsect
Definition: isisraw.h:318
char inst_abrv[ISISCRPT_INST_ABRV_LEN+1]
Definition: isiscrpt.h:352
char icp_version[ICP_NAME_LEN]
Definition: isiscrpt.h:241
int t_nfpp
Definition: isisraw.h:298
std::vector< int > is_waiting
Definition: selogger.h:107
int * mdet
Definition: isisraw.h:273
boost::array< PERIOD, ISISCRPT_MAX_PERIOD > period
Definition: isiscrpt.h:258
SPB_STRUCT spb
Definition: isisraw.h:283
int crat[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:307
SELOGGER_API int __stdcall se_get_measurement_first_run(const char *measurement_id, long &run_number)
Definition: selogger.cpp:974
std::vector< int > is_running
Definition: selogger.h:106
#define MIN_COMP_LEN
Definition: nexuswriter.cpp:10
DAEP_STRUCT daep
Definition: isisraw.h:288
int nlines
Definition: isisraw.h:233
static int addMonitors(IXNeXusFile &ixnf, const ISISCRPT_STRUCT *crpt, const isisU32_t *raw_data, isisU32_t raw_data_size, NXlink *tof_links, NXlink &period_link, bool update, DAEstatus &dstatus)
static int makeDataSlab(NXhandle fileid, const char *data_name, const int *dims_array, int ndims, int compression_type, int spectra_chunk)
int ver8
Definition: isisraw.h:313
int t_ntc1
Definition: isisraw.h:302
IXNeXusFile(nx_error_t error_func=NULL, void *error_arg=NULL)
char sample_type[80]
Definition: isiscrpt.h:417
static int readDeadTimes(float *deadtimes_array, int ndet, const char *file)
char r_title[80]
Definition: isisraw.h:262
char measurement_type[ICP_NAME_LEN]
Definition: isiscrpt.h:439
boost::array< int, ISISCRPT_MAX_NTRG > ntc
number of time channels per CRPT time regime
Definition: isiscrpt.h:346
time_t duration
Definition: isiscrpt.h:257
char user_name[ISISCRPT_USER_NAME_LEN+1]
Definition: isiscrpt.h:353
bool testOptions(Options options)
Definition: nexuswriter.h:167
char inst_name[ISISCRPT_INST_LEN+1]
Definition: isiscrpt.h:351
HDR_STRUCT hdr
Definition: isisraw.h:255
void setLoggerName(const std::string &logger_name)
Definition: IsisBase.h:17
char sample_id[ICP_NAME_LEN]
Definition: isiscrpt.h:440
char sample_orientation[256]
Definition: isiscrpt.h:396
int writeData(const char *data_name, const std::vector< T > &value)
Definition: nexuswriter.h:35
struct ADD_STRUCT add
Definition: isisraw.h:257
int addSlabList(const char *data_name, const unsigned long *value, const int *dims_array, int ndims, int dest_start[], const int *slab_start, const int *slab_size, const std::vector< int > &slab_list)
char measurement_subid[ICP_NAME_LEN]
Definition: isiscrpt.h:438
void enableCompression(int comp_level=NX_COMP_LZW)
Definition: nexuswriter.h:165
int makeLink(const char *name, const char *nxclass, NXlink &link)
int addSlab(const char *data_name, const int *value, const int *dims_array, int ndims, const int *slab_start, const int *slab_size, const int *dest_start)
char instrument_geometry[5]
Definition: isiscrpt.h:401
SELOGGER_API int __stdcall se_wait_for_async()
Definition: selogger.cpp:537
float len2[ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:303
int ver2
Definition: isisraw.h:260
float ut[ISISCRPT_MAX_USER *ISISCRPT_MAX_DETECTOR]
Definition: isiscrpt.h:306
static int readGrouping(int *grouping, int ndet, const char *file)
int ver6
Definition: isisraw.h:296
int spectrumNTC(int spec) const
Definition: isiscrpt.h:804
int addInfoVa(int facility, const char *format,...)
Definition: DAEstatus.cpp:91
std::vector< int > run_status
Definition: selogger.h:105
boost::array< int, ISISCRPT_MAX_NTRG > nsp
number of spectra per CRPT time regime
Definition: isiscrpt.h:334
int len
Definition: isisraw.h:225
char script_name[ICP_NAME_LEN]
Definition: isiscrpt.h:441
boost::array< int, ISISCRPT_MAX_DETECTOR > det_group
0 = monitor, else logical det number
Definition: isiscrpt.h:318
IVPB_STRUCT ivpb
Definition: isisraw.h:268
int m_compression_type
Definition: nexuswriter.h:19
std::vector< int > good_frames
Definition: selogger.h:108
int muon_cerenkov_pulse
Definition: isiscrpt.h:402
int compression_level
Definition: isiscrpt.h:480
std::vector< int64_t > monitor1_sum
Definition: selogger.h:112