code: def check_plate_compatibility(tool, source_plate, sink_plate):
          
          if sink_plate == source_plate.parent:
              return None
  
          # could be that they have the same meta data, but the sink plate is a simplification of the source
          # plate (e.g. when using IndexOf tool)
          if sink_plate.meta_data_id == source_plate.meta_data_id:
              if sink_plate.is_sub_plate(source_plate):
                  return None
              return "Sink plate {} is not a simplification of source plate {}".format(
                  sink_plate.plate_id, source_plate.plate_id)
  
          # Also check to see if the meta data differs by only one value
          meta_data_diff = set(source_plate.ancestor_meta_data_ids) - set(sink_plate.ancestor_meta_data_ids)
          if len(meta_data_diff) == 1:
              # Is the diff value the same as the aggregation meta id passed to the aggregate tool
              if tool.aggregation_meta_data not in meta_data_diff:
                  return "Aggregate tool meta data ({}) " \
                         "does not match the diff between source and sink plates ({})".format(
                          tool.aggregation_meta_data, list(meta_data_diff)[0])
          else:
              return "{} not in source's parent plates".format(sink_plate.plate_id)
docs: Checks whether the source and sink plate are compatible given the tool
  
          :param tool: The tool
          :param source_plate: The source plate
          :param sink_plate: The sink plate
          :return: Either an error, or None
          :type tool: Tool
          :type source_plate: Plate
          :type sink_plate: Plate
          :rtype: None | str