parameters: (self, request:Request, project_id)
docstring: Create a new similarity/NBLAST configuration either by providing
          parameters to have the back-end queue a job or by providing the complete
          matrix data.
          ---
          parameters:
            - name: project_id
              description: Project of the NBLAST configuration
              type: integer
              paramType: path
              required: true
            - name: name
              description: Name of the new NBLAST configuration
              type: string
              paramType: form
              required: true
            - name: source
              description: Where random skeletons come from. Either
              "data", "request" or "backend-random".
              required: false
              defaultValue: "backend-random"
              paramType: form
            - name: distance_breaks
              description: Bin boundaries for the distance in nm. Defaults to [0, 500] in an increasing logarithmic bin sizw
              required: false
              defaultValue: 21
              paramType: form
            - name: dot_breaks
              description: Bin boundaries for the absolute dot product. Defaults to [0, 1] in 0.1 steps.
              required: false
              defaultValue: 10
              paramType: form
            - name: tangent_neighbors
              description: The number of neighbor nodes that should be considered when computing a tangent vector.
              required: false
              defaultValue: 20
              paramType: form
            - name: matching_skeleton_ids
              description: A list of matching skeleton IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_pointset_ids
              description: A list of matching pointset IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_pointcloud_ids
              description: A list of matching pointcloud IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: random_skeleton_ids
              description: A list of random skeleton IDs if <source> is not "request".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_sample_id
              description: An NblastSample foreign key of the matching sample.
              required: false
              defaultValue: None
              paramType: form
            - name: random_sample_id
              description: An NblastSample foreign key tp a random sample.
              required: false
              defaultValue: None
              paramType: form
            - name: scoring
              description: |
                  If passed in a new similarity matrix will be created based on
                  this explict scoring. It is assumed to be a simple list which is
                  organized in rows following each other sequentially. Requires
                  distance binning and dot binning information.
              required: false
docstring_summary: Create a new similarity/NBLAST configuration either by providing
          parameters to have the back-end queue a job or by providing the complete
          matrix data.
          ---
          parameters:
            - name: project_id
              description: Project of the NBLAST configuration
              type: integer
              paramType: path
              required: true
            - name: name
              description: Name of the new NBLAST configuration
              type: string
              paramType: form
              required: true
            - name: source
              description: Where random skeletons come from. Either
              "data", "request" or "backend-random".
              required: false
              defaultValue: "backend-random"
              paramType: form
            - name: distance_breaks
              description: Bin boundaries for the distance in nm. Defaults to [0, 500] in an increasing logarithmic bin sizw
              required: false
              defaultValue: 21
              paramType: form
            - name: dot_breaks
              description: Bin boundaries for the absolute dot product. Defaults to [0, 1] in 0.1 steps.
              required: false
              defaultValue: 10
              paramType: form
            - name: tangent_neighbors
              description: The number of neighbor nodes that should be considered when computing a tangent vector.
              required: false
              defaultValue: 20
              paramType: form
            - name: matching_skeleton_ids
              description: A list of matching skeleton IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_pointset_ids
              description: A list of matching pointset IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_pointcloud_ids
              description: A list of matching pointcloud IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: random_skeleton_ids
              description: A list of random skeleton IDs if <source> is not "request".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_sample_id
              description: An NblastSample foreign key of the matching sample.
              required: false
              defaultValue: None
              paramType: form
            - name: random_sample_id
              description: An NblastSample foreign key tp a random sample.
              required: false
              defaultValue: None
              paramType: form
            - name: scoring
              description: |
                  If passed in a new similarity matrix will be created based on
                  this explict scoring. It is assumed to be a simple list which is
                  organized in rows following each other sequentially. Requires
                  distance binning and dot binning information.
              required: false
docstring_tokens: Create a new similarity / NBLAST configuration either by providing parameters to have the back - end queue a job or by providing the complete matrix data . --- parameters : - name : project_id description : Project of the NBLAST configuration type : integer paramType : path required : true - name : name description : Name of the new NBLAST configuration type : string paramType : form required : true - name : source description : Where random skeletons come from . Either data request or backend - random . required : false defaultValue : backend - random paramType : form - name : distance_breaks description : Bin boundaries for the distance in nm . Defaults to [ 0 500 ] in an increasing logarithmic bin sizw required : false defaultValue : 21 paramType : form - name : dot_breaks description : Bin boundaries for the absolute dot product . Defaults to [ 0 1 ] in 0 . 1 steps . required : false defaultValue : 10 paramType : form - name : tangent_neighbors description : The number of neighbor nodes that should be considered when computing a tangent vector . required : false defaultValue : 20 paramType : form - name : matching_skeleton_ids description : A list of matching skeleton IDs if <source > is not data . required : false defaultValue : [] paramType : form - name : matching_pointset_ids description : A list of matching pointset IDs if <source > is not data . required : false defaultValue : [] paramType : form - name : matching_pointcloud_ids description : A list of matching pointcloud IDs if <source > is not data . required : false defaultValue : [] paramType : form - name : random_skeleton_ids description : A list of random skeleton IDs if <source > is not request . required : false defaultValue : [] paramType : form - name : matching_sample_id description : An NblastSample foreign key of the matching sample . required : false defaultValue : None paramType : form - name : random_sample_id description : An NblastSample foreign key tp a random sample . required : false defaultValue : None paramType : form - name : scoring description : | If passed in a new similarity matrix will be created based on this explict scoring . It is assumed to be a simple list which is organized in rows following each other sequentially . Requires distance binning and dot binning information . required : false
function: def put(self, request:Request, project_id) -> Response:
          """Create a new similarity/NBLAST configuration either by providing
          parameters to have the back-end queue a job or by providing the complete
          matrix data.
          ---
          parameters:
            - name: project_id
              description: Project of the NBLAST configuration
              type: integer
              paramType: path
              required: true
            - name: name
              description: Name of the new NBLAST configuration
              type: string
              paramType: form
              required: true
            - name: source
              description: Where random skeletons come from. Either
              "data", "request" or "backend-random".
              required: false
              defaultValue: "backend-random"
              paramType: form
            - name: distance_breaks
              description: Bin boundaries for the distance in nm. Defaults to [0, 500] in an increasing logarithmic bin sizw
              required: false
              defaultValue: 21
              paramType: form
            - name: dot_breaks
              description: Bin boundaries for the absolute dot product. Defaults to [0, 1] in 0.1 steps.
              required: false
              defaultValue: 10
              paramType: form
            - name: tangent_neighbors
              description: The number of neighbor nodes that should be considered when computing a tangent vector.
              required: false
              defaultValue: 20
              paramType: form
            - name: matching_skeleton_ids
              description: A list of matching skeleton IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_pointset_ids
              description: A list of matching pointset IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_pointcloud_ids
              description: A list of matching pointcloud IDs if <source> is not "data".
              required: false
              defaultValue: []
              paramType: form
            - name: random_skeleton_ids
              description: A list of random skeleton IDs if <source> is not "request".
              required: false
              defaultValue: []
              paramType: form
            - name: matching_sample_id
              description: An NblastSample foreign key of the matching sample.
              required: false
              defaultValue: None
              paramType: form
            - name: random_sample_id
              description: An NblastSample foreign key tp a random sample.
              required: false
              defaultValue: None
              paramType: form
            - name: scoring
              description: |
                  If passed in a new similarity matrix will be created based on
                  this explict scoring. It is assumed to be a simple list which is
                  organized in rows following each other sequentially. Requires
                  distance binning and dot binning information.
              required: false
          """
          name = request.data.get('name')
          if not name:
              raise ValueError("Need name")
  
          # Cancel if user isn't allowed to queue computation tasks
          p = Project.objects.get(pk=project_id)
  
          distance_breaks = get_request_list(request.data, 'distance_breaks', map_fn=float)
          dot_breaks = get_request_list(request.data, 'dot_breaks', map_fn=float)
  
          scoring = get_request_list(request.data, 'scoring', map_fn=float)
          if not scoring:
              has_role = check_user_role(request.user, p, UserRole.QueueComputeTask)
              if not has_role:
                  raise PermissionError("User " + str(request.user.id) +
                          " does not have permission to queue computation tasks.")
  
          source = request.data.get('source', 'backend-random')
          tangent_neighbors = int(request.data.get('tangent_neighbors', '20'))
          matching_sample_id = int(request.data.get('matching_sample_id')) \
                  if 'matching_sample_id' in request.data else None
          random_sample_id = int(request.data.get('random_sample_id')) \
                  if 'random_sample_id' in request.data else None
          min_length = float(request.data.get('min_length', 0))
          min_nodes = int(request.data.get('min_nodes', 50))
          user_id = request.user.id
  
          matching_skeleton_ids = get_request_list(request.data,
                  'matching_skeleton_ids', map_fn=int)
          matching_pointset_ids = get_request_list(request.data,
                  'matching_pointset_ids', map_fn=int)
          matching_pointcloud_ids = get_request_list(request.data,
                  'matching_pointcloud_ids', map_fn=int)
          random_skeleton_ids = get_request_list(request.data,
                  'random_skeleton_ids', map_fn=int)
          matching_meta = request.POST.get('matching_meta')
          if matching_meta:
              matching_meta = json.loads(matching_meta)
          matching_subset = request.POST.get('matching_subset')
          if matching_subset:
              matching_subset = json.loads(matching_subset)
  
              if type(matching_subset) != list:
                  raise ValueError("Expected matching_subset to be a list")
  
              for subset in matching_subset:
                  if type(subset) != list:
                      raise ValueError("Expected all matching_subset elements to be list")
                  for element in subset:
                      if type(element) != list or len(element) != 2:
                          raise ValueError("Expeceted subset elements to be lists with two elements")
                      if type(element[0]) not in (int, list) or type(element[1]) != int:
                          raise ValueError("Expected subset selements to consist of ints or lists of ints")
  
          # Load and store point sets, if there are any.
          if matching_pointset_ids and matching_meta:
              created_ids = []
              for pointset_id in matching_pointset_ids:
                  pointset_data = matching_meta.get(str(pointset_id))
                  if not pointset_data:
                      raise ValueError(f"Could not find data for pointset {pointset_id}")
                  flat_points = list(chain.from_iterable(pointset_data['points']))
                  pointset = PointSet.objects.create(project_id=project_id,
                          user=request.user, name=pointset_data['name'],
                          description=pointset_data.get('description'),
                          points=flat_points)
                  pointset.save()
                  created_ids.append(pointset.id)
  
                  # Update matching_subset with actual ID of point set. The subset
                  # is a list of lists that represent the subsets. Each subset
                  # element is a list of two elements [type, id]. For skeletons
                  # the ID is 0, for point sets the ID is 1 and for point clouds
                  # the ID is 2.
                  if matching_subset:
                      for subset in matching_subset:
                          for element in subset:
                              if element[0] == 1 and element[1] == pointset_id:
                                  element[1] = pointset.id
  
              # Update matching point set IDs with actual
              matching_pointset_ids = created_ids
  
          if not dot_breaks:
              dot_breaks = NblastConfigDefaultDotBreaks
  
          if not distance_breaks:
              distance_breaks = NblastConfigDefaultDistanceBreaks
  
          # Make sure bins and breaks match
  
          if scoring:
              config = self.add_from_raw_data(project_id, request.user.id, name,
                      scoring, distance_breaks, dot_breaks, tangent_neighbors)
              return Response(serialize_config(config))
          elif source == 'request':
              if not matching_skeleton_ids and not matching_pointset_ids:
                  raise ValueError("Need matching_skeleton_ids or matching_pointset_ids")
              if not random_skeleton_ids:
                  raise ValueError("Need random_skeleton_ids")
              config = self.add_delayed(project_id, user_id, name, matching_skeleton_ids,
                      matching_pointset_ids, random_skeleton_ids, distance_breaks,
                      dot_breaks, tangent_neighbors=tangent_neighbors,
                      matching_subset=matching_subset)
              return Response(serialize_config(config))
          elif source == 'backend-random':
              if not matching_skeleton_ids and not matching_pointset_ids:
                  raise ValueError("Need matching_skeleton_ids or matching_pointset_ids")
              n_random_skeletons = int(request.data.get('n_random_skeletons', 5000))
  
              # Cancel if user isn't allowed to queue computation tasks
              p = Project.objects.get(pk=project_id)
              has_role = check_user_role(request.user, p, UserRole.QueueComputeTask)
              if not has_role:
                  raise PermissionError("User " + str(request.user.id) +
                          " does not have permission to queue computation tasks.")
  
              config = self.compute_random_and_add_delayed(project_id, user_id, name,
                      matching_skeleton_ids, matching_pointset_ids,
                      matching_pointcloud_ids, distance_breaks, dot_breaks, None,
                      None, n_random_skeletons, min_length, min_nodes,
                      tangent_neighbors, matching_subset)
              return Response(serialize_config(config))
          else:
              raise ValueError("Unknown source: " + source)
function_tokens: def put ( self , request : Request , project_id ) -> Response : name = request . data . get ( 'name' ) if not name : raise ValueError ( "Need name" ) # Cancel if user isn't allowed to queue computation tasks p = Project . objects . get ( pk = project_id ) distance_breaks = get_request_list ( request . data , 'distance_breaks' , map_fn = float ) dot_breaks = get_request_list ( request . data , 'dot_breaks' , map_fn = float ) scoring = get_request_list ( request . data , 'scoring' , map_fn = float ) if not scoring : has_role = check_user_role ( request . user , p , UserRole . QueueComputeTask ) if not has_role : raise PermissionError ( "User " + str ( request . user . id ) + " does not have permission to queue computation tasks." ) source = request . data . get ( 'source' , 'backend-random' ) tangent_neighbors = int ( request . data . get ( 'tangent_neighbors' , '20' ) ) matching_sample_id = int ( request . data . get ( 'matching_sample_id' ) ) if 'matching_sample_id' in request . data else None random_sample_id = int ( request . data . get ( 'random_sample_id' ) ) if 'random_sample_id' in request . data else None min_length = float ( request . data . get ( 'min_length' , 0 ) ) min_nodes = int ( request . data . get ( 'min_nodes' , 50 ) ) user_id = request . user . id matching_skeleton_ids = get_request_list ( request . data , 'matching_skeleton_ids' , map_fn = int ) matching_pointset_ids = get_request_list ( request . data , 'matching_pointset_ids' , map_fn = int ) matching_pointcloud_ids = get_request_list ( request . data , 'matching_pointcloud_ids' , map_fn = int ) random_skeleton_ids = get_request_list ( request . data , 'random_skeleton_ids' , map_fn = int ) matching_meta = request . POST . get ( 'matching_meta' ) if matching_meta : matching_meta = json . loads ( matching_meta ) matching_subset = request . POST . get ( 'matching_subset' ) if matching_subset : matching_subset = json . loads ( matching_subset ) if type ( matching_subset ) != list : raise ValueError ( "Expected matching_subset to be a list" ) for subset in matching_subset : if type ( subset ) != list : raise ValueError ( "Expected all matching_subset elements to be list" ) for element in subset : if type ( element ) != list or len ( element ) != 2 : raise ValueError ( "Expeceted subset elements to be lists with two elements" ) if type ( element [ 0 ] ) not in ( int , list ) or type ( element [ 1 ] ) != int : raise ValueError ( "Expected subset selements to consist of ints or lists of ints" ) # Load and store point sets, if there are any. if matching_pointset_ids and matching_meta : created_ids = [ ] for pointset_id in matching_pointset_ids : pointset_data = matching_meta . get ( str ( pointset_id ) ) if not pointset_data : raise ValueError ( f"Could not find data for pointset {pointset_id}" ) flat_points = list ( chain . from_iterable ( pointset_data [ 'points' ] ) ) pointset = PointSet . objects . create ( project_id = project_id , user = request . user , name = pointset_data [ 'name' ] , description = pointset_data . get ( 'description' ) , points = flat_points ) pointset . save ( ) created_ids . append ( pointset . id ) # Update matching_subset with actual ID of point set. The subset # is a list of lists that represent the subsets. Each subset # element is a list of two elements [type, id]. For skeletons # the ID is 0, for point sets the ID is 1 and for point clouds # the ID is 2. if matching_subset : for subset in matching_subset : for element in subset : if element [ 0 ] == 1 and element [ 1 ] == pointset_id : element [ 1 ] = pointset . id # Update matching point set IDs with actual matching_pointset_ids = created_ids if not dot_breaks : dot_breaks = NblastConfigDefaultDotBreaks if not distance_breaks : distance_breaks = NblastConfigDefaultDistanceBreaks # Make sure bins and breaks match if scoring : config = self . add_from_raw_data ( project_id , request . user . id , name , scoring , distance_breaks , dot_breaks , tangent_neighbors ) return Response ( serialize_config ( config ) ) elif source == 'request' : if not matching_skeleton_ids and not matching_pointset_ids : raise ValueError ( "Need matching_skeleton_ids or matching_pointset_ids" ) if not random_skeleton_ids : raise ValueError ( "Need random_skeleton_ids" ) config = self . add_delayed ( project_id , user_id , name , matching_skeleton_ids , matching_pointset_ids , random_skeleton_ids , distance_breaks , dot_breaks , tangent_neighbors = tangent_neighbors , matching_subset = matching_subset ) return Response ( serialize_config ( config ) ) elif source == 'backend-random' : if not matching_skeleton_ids and not matching_pointset_ids : raise ValueError ( "Need matching_skeleton_ids or matching_pointset_ids" ) n_random_skeletons = int ( request . data . get ( 'n_random_skeletons' , 5000 ) ) # Cancel if user isn't allowed to queue computation tasks p = Project . objects . get ( pk = project_id ) has_role = check_user_role ( request . user , p , UserRole . QueueComputeTask ) if not has_role : raise PermissionError ( "User " + str ( request . user . id ) + " does not have permission to queue computation tasks." ) config = self . compute_random_and_add_delayed ( project_id , user_id , name , matching_skeleton_ids , matching_pointset_ids , matching_pointcloud_ids , distance_breaks , dot_breaks , None , None , n_random_skeletons , min_length , min_nodes , tangent_neighbors , matching_subset ) return Response ( serialize_config ( config ) ) else : raise ValueError ( "Unknown source: " + source )