docs: def _make_inputnode(self, frequency):
          """
          Generates an input node for the given frequency. It also adds implicit
          file format conversion nodes to the pipeline.
  
          Parameters
          ----------
          frequency : str
              The frequency (i.e. 'per_session', 'per_visit', 'per_subject' or
              'per_study') of the input node to retrieve
          """
          # Check to see whether there are any outputs for the given frequency
          inputs = list(self.frequency_inputs(frequency))
          # Get list of input names for the requested frequency, addding fields
          # to hold iterator IDs
          input_names = [i.name for i in inputs]
          input_names.extend(self.study.FREQUENCIES[frequency])
          if not input_names:
              raise ArcanaError(
                  "No inputs to '{}' pipeline for requested freqency '{}'"
                  .format(self.name, frequency))
          # Generate input node and connect it to appropriate nodes
          inputnode = self.add('{}_inputnode'.format(frequency),
                               IdentityInterface(fields=input_names))
          # Loop through list of nodes connected to study data specs and
          # connect them to the newly created input node
          for input in inputs:  # @ReservedAssignment
              # Keep track of previous conversion nodes to avoid replicating the
              # conversion for inputs that are used in multiple places
              prev_conv_nodes = {}
              for (node, node_in, format,  # @ReservedAssignment @IgnorePep8
                   conv_kwargs) in self._input_conns[input.name]:
                  # If fileset formats differ between study and pipeline
                  # inputs create converter node (if one hasn't been already)
                  # and connect input to that before connecting to inputnode
                  if self.requires_conversion(input, format):
                      try:
                          conv = format.converter_from(input.format,
                                                       **conv_kwargs)
                      except ArcanaNoConverterError as e:
                          e.msg += (
                              "which is required to convert '{}' from {} to {} "
                              "for '{}' input of '{}' node".format(
                                  input.name, input.format, format, node_in,
                                  node.name))
                          raise e
                      try:
                          in_node = prev_conv_nodes[format.name]
                      except KeyError:
                          in_node = prev_conv_nodes[format.name] = self.add(
                              'conv_{}_to_{}_format'.format(input.name,
                                                            format.name),
                              conv.interface,
                              inputs={conv.input: (inputnode, input.name)},
                              requirements=conv.requirements,
                              mem_gb=conv.mem_gb,
                              wall_time=conv.wall_time)
                      in_node_out = conv.output
                  else:
                      in_node = inputnode
                      in_node_out = input.name
                  self.connect(in_node, in_node_out, node, node_in)
          # Connect iterator inputs
          for iterator, conns in self._iterator_conns.items():
              # Check to see if this is the right frequency for the iterator
              # input, i.e. if it is the only iterator for this frequency
              if self.study.FREQUENCIES[frequency] == (iterator,):
                  for (node, node_in, format) in conns:  # @ReservedAssignment
                      self.connect(inputnode, iterator, node, node_in)
          return inputnode