Example #1
0
  /** Validate group 'data' of type NXdata. */
  private void validateGroup_NXentry_data(final NXdata group) throws NexusValidationException {
    // validate that the group is not null
    validateGroupNotNull("data", NXdata.class, group);
    clearLocalGroupDimensionPlaceholderValues();

    // validate field 'azimuthal' of type NX_FLOAT. Note: field not defined in base class.
    final IDataset azimuthal = group.getDataset("azimuthal");
    validateFieldNotNull("azimuthal", azimuthal);
    validateFieldType("azimuthal", azimuthal, NX_FLOAT);
    validateFieldUnits("azimuthal", azimuthal, NX_ANGLE);

    // validate field 'azimuthal_width' of type NX_FLOAT. Note: field not defined in base class.
    final IDataset azimuthal_width = group.getDataset("azimuthal_width");
    validateFieldNotNull("azimuthal_width", azimuthal_width);
    validateFieldType("azimuthal_width", azimuthal_width, NX_FLOAT);
    validateFieldUnits("azimuthal_width", azimuthal_width, NX_ANGLE);

    // validate field 'polar' of type NX_FLOAT. Note: field not defined in base class.
    final IDataset polar = group.getDataset("polar");
    validateFieldNotNull("polar", polar);
    validateFieldType("polar", polar, NX_FLOAT);
    validateFieldUnits("polar", polar, NX_ANGLE);

    // validate field 'polar_width' of type NX_FLOAT. Note: field not defined in base class.
    final IDataset polar_width = group.getDataset("polar_width");
    validateFieldNotNull("polar_width", polar_width);
    validateFieldType("polar_width", polar_width, NX_FLOAT);
    validateFieldUnits("polar_width", polar_width, NX_ANGLE);

    // validate field 'distance' of type NX_FLOAT. Note: field not defined in base class.
    final IDataset distance = group.getDataset("distance");
    validateFieldNotNull("distance", distance);
    validateFieldType("distance", distance, NX_FLOAT);
    validateFieldUnits("distance", distance, NX_LENGTH);

    // validate field 'data' of type NX_NUMBER.
    final IDataset data = group.getData();
    validateFieldNotNull("data", data);
    validateFieldType("data", data, NX_NUMBER);
    validateFieldDimensions("data", data, "NXdata", "n");

    // validate field 'error' of type NX_NUMBER. Note: field not defined in base class.
    final IDataset error = group.getDataset("error");
    validateFieldNotNull("error", error);
    validateFieldType("error", error, NX_NUMBER);

    // validate field 'energy' of type NX_FLOAT. Note: field not defined in base class.
    final IDataset energy = group.getDataset("energy");
    validateFieldNotNull("energy", energy);
    validateFieldType("energy", energy, NX_FLOAT);
    validateFieldUnits("energy", energy, NX_ENERGY);
  }
  private void checkNexusFile(
      IRunnableDevice<ScanModel> scanner, List<ScanMetadata> scanMetadata, int... sizes)
      throws Exception {

    final ScanModel scanModel = ((AbstractRunnableDevice<ScanModel>) scanner).getModel();
    assertEquals(DeviceState.READY, scanner.getDeviceState());

    NXroot rootNode = getNexusRoot(scanner);
    NXentry entry = rootNode.getEntry();
    checkMetadata(entry, scanMetadata);
    // check that the scan points have been written correctly
    assertScanPointsGroup(entry, sizes);

    NXinstrument instrument = entry.getInstrument();

    LinkedHashMap<String, List<String>> signalFieldAxes = new LinkedHashMap<>();
    // axis for additional dimensions of a datafield, e.g. image
    signalFieldAxes.put(NXdetector.NX_DATA, Arrays.asList("real", "imaginary"));
    signalFieldAxes.put("spectrum", Arrays.asList("spectrum_axis"));
    signalFieldAxes.put("value", Collections.emptyList());

    String detectorName = scanModel.getDetectors().get(0).getName();
    NXdetector detector = instrument.getDetector(detectorName);
    // map of detector data field to name of nxData group where that field
    // is the @signal field
    Map<String, String> expectedDataGroupNames =
        signalFieldAxes
            .keySet()
            .stream()
            .collect(
                Collectors.toMap(
                    Function.identity(),
                    x -> detectorName + (x.equals(NXdetector.NX_DATA) ? "" : "_" + x)));

    // validate the main NXdata generated by the NexusDataBuilder
    Map<String, NXdata> nxDataGroups = entry.getChildren(NXdata.class);
    assertEquals(signalFieldAxes.size(), nxDataGroups.size());
    assertTrue(nxDataGroups.keySet().containsAll(expectedDataGroupNames.values()));
    for (String nxDataGroupName : nxDataGroups.keySet()) {
      NXdata nxData = entry.getData(nxDataGroupName);

      String sourceFieldName =
          nxDataGroupName.equals(detectorName)
              ? NXdetector.NX_DATA
              : nxDataGroupName.substring(nxDataGroupName.indexOf('_') + 1);
      assertSignal(nxData, sourceFieldName);
      // check the nxData's signal field is a link to the appropriate source data node of the
      // detector
      DataNode dataNode = detector.getDataNode(sourceFieldName);
      IDataset dataset = dataNode.getDataset().getSlice();
      assertSame(dataNode, nxData.getDataNode(sourceFieldName));
      assertTarget(
          nxData,
          sourceFieldName,
          rootNode,
          "/entry/instrument/" + detectorName + "/" + sourceFieldName);

      // check that the other primary data fields of the detector haven't been added to this NXdata
      for (String primaryDataFieldName : signalFieldAxes.keySet()) {
        if (!primaryDataFieldName.equals(sourceFieldName)) {
          assertNull(nxData.getDataNode(primaryDataFieldName));
        }
      }

      int[] shape = dataset.getShape();
      for (int i = 0; i < sizes.length; i++) assertEquals(sizes[i], shape[i]);

      // Make sure none of the numbers are NaNs. The detector
      // is expected to fill this scan with non-nulls.
      final PositionIterator it = new PositionIterator(shape);
      while (it.hasNext()) {
        int[] next = it.getPos();
        assertFalse(Double.isNaN(dataset.getDouble(next)));
      }

      // Check axes
      final IPosition pos = scanModel.getPositionIterable().iterator().next();
      final Collection<String> scannableNames = pos.getNames();

      // Append _value_demand to each name in list, then add detector axis fields to result
      List<String> expectedAxesNames =
          Stream.concat(
                  scannableNames.stream().map(x -> x + "_value_set"),
                  signalFieldAxes.get(sourceFieldName).stream())
              .collect(Collectors.toList());
      assertAxes(nxData, expectedAxesNames.toArray(new String[expectedAxesNames.size()]));

      int[] defaultDimensionMappings = IntStream.range(0, sizes.length).toArray();
      int i = -1;
      for (String scannableName : scannableNames) {

        i++;
        NXpositioner positioner = instrument.getPositioner(scannableName);
        assertNotNull(positioner);

        dataNode = positioner.getDataNode("value_set");
        dataset = dataNode.getDataset().getSlice();
        shape = dataset.getShape();
        assertEquals(1, shape.length);
        assertEquals(sizes[i], shape[0]);

        String nxDataFieldName = scannableName + "_value_set";
        assertSame(dataNode, nxData.getDataNode(nxDataFieldName));
        assertIndices(nxData, nxDataFieldName, i);
        assertTarget(
            nxData, nxDataFieldName, rootNode, "/entry/instrument/" + scannableName + "/value_set");

        // Actual values should be scanD
        dataNode = positioner.getDataNode(NXpositioner.NX_VALUE);
        dataset = dataNode.getDataset().getSlice();
        shape = dataset.getShape();
        assertArrayEquals(sizes, shape);

        nxDataFieldName = scannableName + "_" + NXpositioner.NX_VALUE;
        assertSame(dataNode, nxData.getDataNode(nxDataFieldName));
        assertIndices(nxData, nxDataFieldName, defaultDimensionMappings);
        assertTarget(
            nxData,
            nxDataFieldName,
            rootNode,
            "/entry/instrument/" + scannableName + "/" + NXpositioner.NX_VALUE);
      }
    }
  }