int tclcommand_observable_com_force(Tcl_Interp* interp, int argc, char** argv, int* change, observable* obs) {
  IntList* ids;
  int temp, blocksize;
  if (parse_id_list(interp, argc-1, argv+1, &temp, &ids) != TCL_OK ) 
    return TCL_ERROR;
  argc-=temp+1;
  argv+=temp+1;
  for ( int i = 0; i < argc; i++) {
    printf("%s\n", argv[i]);
  }
  if (argc>0 && ARG0_IS_S("blocked")) {
    if (argc >= 2 && ARG1_IS_I(blocksize) && (ids->n % blocksize ==0 )) {
      obs->fun=&observable_blocked_com_force;
      obs->args=ids;
      obs->n=3*ids->n/blocksize;
      *change=3+temp;
      printf("found %d ids and a blocksize of %d, that makes %d dimensions\n", ids->n, blocksize, obs->n);
      return TCL_OK;
    } else {
      Tcl_AppendResult(interp, "com_velocity blocked expected integer argument that fits the number of particles\n", (char *)NULL );
      return TCL_ERROR;
    }
  } else /* if nonblocked com is to be taken */ {
    obs->fun=&observable_com_force;
    obs->args=ids;
    obs->n=3;
    *change=1+temp;
    return TCL_OK;
  }
}
int tclcommand_observable_particle_forces(Tcl_Interp* interp, int argc, char** argv, int* change, observable* obs) {
  IntList* ids;
  int temp;
  if (parse_id_list(interp, argc-1, argv+1, &temp, &ids) != TCL_OK ) 
     return TCL_ERROR;
  obs->fun = &observable_particle_forces;
  obs->args=(void*)ids;
  obs->n=3*ids->n;
  *change=1+temp;
  return TCL_OK;
}
int tclcommand_observable_interacts_with(Tcl_Interp* interp, int argc, char** argv, int* change, observable* obs) {
  IntList *ids1, *ids2;
  int temp;
  double cutoff;
  obs->calculate=&observable_calc_interacts_with;
  obs->update=0;
  ids1=(IntList*)malloc(sizeof(IntList));
  ids2=(IntList*)malloc(sizeof(IntList));
  iw_params* iw_params_p=(iw_params*) malloc(sizeof(iw_params));
  if (parse_id_list(interp, argc-1, argv+1, &temp, &ids1) != TCL_OK ) {
    free(ids1);
    free(ids2);
    free(iw_params_p);
    return TCL_ERROR;
  }
  iw_params_p=(iw_params*)malloc(sizeof(iw_params));
  iw_params_p->ids1=ids1;
  *change=1+temp;
  if (parse_id_list(interp, argc-3, argv+3, &temp, &ids2) != TCL_OK ) {
    free(ids1);
    free(ids2);
    free(iw_params_p);
    return TCL_ERROR;
  }
  *change+=temp;
  iw_params_p->ids2=ids2;
  if ( argc < 5 || !ARG_IS_D(5,cutoff)) {
    Tcl_AppendResult(interp, "Usage: analyze correlation ... interacts_with id_list1 id_list2 cutoff", (char *)NULL);
    free(ids1);
    free(ids2);
    free(iw_params_p);
  return TCL_ERROR;
  } 
  *change+=1;
  iw_params_p->cutoff=cutoff;
  obs->container=(void*)iw_params_p;
  obs->n=ids1->n; // number of ids from the 1st argument
  obs->last_value=(double*)malloc(obs->n*sizeof(double));
  return TCL_OK;
}
int tclcommand_observable_particle_forces(Tcl_Interp* interp, int argc, char** argv, int* change, observable* obs) {
  IntList* ids;
  int temp;
  if (parse_id_list(interp, argc-1, argv+1, &temp, &ids) != TCL_OK ) 
     return TCL_ERROR;
  obs->calculate=&observable_calc_particle_forces;
  obs->update=0;
  obs->container=(void*)ids;
  obs->n=3*ids->n;
  obs->last_value=(double*)malloc(obs->n*sizeof(double));
  *change=1+temp;
  return TCL_OK;
}
int tclcommand_observable_dipole_moment(Tcl_Interp* interp, int argc, char** argv, int* change, observable* obs) {
#ifdef ELECTROSTATICS
  int temp;
  IntList* ids;
  obs->fun = &observable_dipole_moment;
  if (! parse_id_list(interp, argc-1, argv+1, &temp, &ids) == TCL_OK ) 
    return TCL_ERROR;
  obs->args=(void*)ids;
  obs->n=3;
  *change=1+temp;
  return TCL_OK;
#else
  Tcl_AppendResult(interp, "Feature ELECTROSTATICS needed for observable currents", (char *)NULL);
  return TCL_ERROR;
#endif
}
int tclcommand_observable_dipole_moment(Tcl_Interp* interp, int argc, char** argv, int* change, observable* obs) {
#ifdef ELECTROSTATICS
  int temp;
  IntList* ids;
  obs->calculate=&observable_calc_dipole_moment;
  obs->update=0;
  if (parse_id_list(interp, argc-1, argv+1, &temp, &ids) != TCL_OK ) 
    return TCL_ERROR;
  obs->container=(void*)ids;
  obs->n=3;
  obs->last_value=(double*)malloc(obs->n*sizeof(double));
  *change=1+temp;
  return TCL_OK;
#else
  Tcl_AppendResult(interp, "Feature ELECTROSTATICS needed for observable currents", (char *)NULL);
  return TCL_ERROR;
#endif
}
Ejemplo n.º 7
0
int kowhai_protocol_parse(void* proto_packet, int packet_size, struct kowhai_protocol_t* protocol)
{
    int required_size = sizeof(struct kowhai_protocol_header_t);
    memset(protocol, 0, sizeof(struct kowhai_protocol_t));

    // check packet is large enough for header
    if (packet_size < required_size)
        return KOW_STATUS_PACKET_BUFFER_TOO_SMALL;
    memcpy(&protocol->header, proto_packet, required_size);

    switch (protocol->header.command)
    {
        case KOW_CMD_GET_VERSION:
            return KOW_STATUS_OK;
        case KOW_CMD_GET_VERSION_ACK:
            return parse_version((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload);
        case KOW_CMD_GET_TREE_LIST:
            return KOW_STATUS_OK;
        case KOW_CMD_GET_TREE_LIST_ACK:
        case KOW_CMD_GET_TREE_LIST_ACK_END:
        case KOW_CMD_GET_FUNCTION_LIST_ACK:
        case KOW_CMD_GET_FUNCTION_LIST_ACK_END:
            return parse_id_list((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload);
        case KOW_CMD_READ_DATA:
            return parse_symbols((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload, &required_size);
        case KOW_CMD_WRITE_DATA:
        case KOW_CMD_WRITE_DATA_END:
        case KOW_CMD_WRITE_DATA_ACK:
        case KOW_CMD_READ_DATA_ACK:
        case KOW_CMD_READ_DATA_ACK_END:
            return parse_data_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload);
        case KOW_CMD_READ_DESCRIPTOR:
            // read descriptor command requires no more parameters
            return KOW_STATUS_OK;
        case KOW_CMD_READ_DESCRIPTOR_ACK:
        case KOW_CMD_READ_DESCRIPTOR_ACK_END:
            return parse_descriptor_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload);
        case KOW_CMD_GET_FUNCTION_LIST:
        case KOW_CMD_GET_FUNCTION_DETAILS:
            // get function list/details command requires no more parameters
            return KOW_STATUS_OK;
        case KOW_CMD_GET_FUNCTION_DETAILS_ACK:
            return parse_function_details((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload.spec.function_details);
        case KOW_CMD_CALL_FUNCTION:
        case KOW_CMD_CALL_FUNCTION_ACK:
        case KOW_CMD_CALL_FUNCTION_RESULT:
        case KOW_CMD_CALL_FUNCTION_RESULT_END:
            return parse_function_call((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload);
        case KOW_CMD_CALL_FUNCTION_FAILED:
            return KOW_STATUS_OK;
        case KOW_CMD_EVENT:
        case KOW_CMD_EVENT_END:
            return parse_event((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload);
        case KOW_CMD_GET_SYMBOL_LIST:
            return KOW_STATUS_OK;
        case KOW_CMD_GET_SYMBOL_LIST_ACK:
        case KOW_CMD_GET_SYMBOL_LIST_ACK_END:
            return parse_string_list((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload);

        // error codes
        case KOW_CMD_ERROR_INVALID_COMMAND:
        case KOW_CMD_ERROR_INVALID_FUNCTION_ID:
        case KOW_CMD_ERROR_INVALID_PAYLOAD_OFFSET:
        case KOW_CMD_ERROR_INVALID_PAYLOAD_SIZE:
        case KOW_CMD_ERROR_INVALID_SEQUENCE:
        case KOW_CMD_ERROR_INVALID_SYMBOL_PATH:
        case KOW_CMD_ERROR_INVALID_TREE_ID:
        case KOW_CMD_ERROR_NO_DATA:
            return KOW_STATUS_OK;
        default:
            return KOW_STATUS_INVALID_PROTOCOL_COMMAND;
    }
}
int tclcommand_parse_profile(Tcl_Interp* interp, int argc, char** argv, int* change, int* dim_A, profile_data** pdata_) {
  int temp;
  *change=0;
  profile_data* pdata=(profile_data*)malloc(sizeof(profile_data));
  *pdata_ = pdata;
  pdata->id_list=0;
  pdata->minx=0;
  pdata->maxx=box_l[0];
  pdata->xbins=1;
  pdata->miny=0;
  pdata->maxy=box_l[1];
  pdata->ybins=1;
  pdata->minz=0;
  pdata->maxz=box_l[2];
  pdata->zbins=1;
  while (argc>0) {
    if (ARG0_IS_S("ids") || ARG0_IS_S("types") || ARG0_IS_S("all")) {
      if (!parse_id_list(interp, argc, argv, &temp, &pdata->id_list )==TCL_OK) {
        Tcl_AppendResult(interp, "Error reading profile: Error parsing particle id information\n" , (char *)NULL);
        return TCL_ERROR;
      } else {
        *change+=temp;
        argc-=temp;
        argv+=temp;
      }
    } else if ( ARG0_IS_S("minx")){
      if (argc>1 && ARG1_IS_D(pdata->minx)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read minz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else  if ( ARG0_IS_S("maxx") ) {
      if (argc>1 && ARG1_IS_D(pdata->maxx)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read maxz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else  if (ARG0_IS_S("xbins")) {
      if (argc>1 && ARG1_IS_I(pdata->xbins)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read nbins\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if ( ARG0_IS_S("miny")){
      if (argc>1 && ARG1_IS_D(pdata->miny)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read minz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else  if ( ARG0_IS_S("maxy") ) {
      if (argc>1 && ARG1_IS_D(pdata->maxy)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read maxz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else  if (ARG0_IS_S("ybins")) {
      if (argc>1 && ARG1_IS_I(pdata->ybins)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read nbins\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if ( ARG0_IS_S("minz")){
      if (argc>1 && ARG1_IS_D(pdata->minz)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read minz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else  if ( ARG0_IS_S("maxz") ) {
      if (argc>1 && ARG1_IS_D(pdata->maxz)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read maxz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else  if (ARG0_IS_S("zbins")) {
      if (argc>1 && ARG1_IS_I(pdata->zbins)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read nbins\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else {
      Tcl_AppendResult(interp, "Error in radial_profile: understand argument ", argv[0], "\n" , (char *)NULL);
      return TCL_ERROR;
    }
  }
  
  temp=0;
  if (pdata->xbins <= 0 || pdata->ybins <=0 || pdata->zbins <= 0) {
    Tcl_AppendResult(interp, "Error in profile: the bin number in each direction must be >=1\n" , (char *)NULL);
    temp=1;
  }
  if (temp)
    return TCL_ERROR;
  else
    return TCL_OK;
}
int tclcommand_parse_radial_profile(Tcl_Interp* interp, int argc, char** argv, int* change, int* dim_A, radial_profile_data** pdata_) {
  int temp;
  *change=0;
  radial_profile_data* pdata=(radial_profile_data*)malloc(sizeof(radial_profile_data));
  *pdata_ = pdata;
  pdata->id_list=0;
  if (box_l[0]<box_l[1]) 
    pdata->maxr = box_l[0];
  else 
    pdata->maxr = box_l[1];
  pdata->minr=0;
  pdata->maxphi=PI;
  pdata->minphi=-PI;
  pdata->minz=-box_l[2]/2.;
  pdata->maxz=+box_l[2]/2.;
  pdata->center[0]=box_l[0]/2.;pdata->center[1]=box_l[1]/2.;pdata->center[2]=box_l[2]/2.;
  pdata->rbins=1;
  pdata->zbins=1;
  pdata->phibins=1;
  pdata->axis[0]=0.;
  pdata->axis[1]=0.;
  pdata->axis[2]=1.;
  if (argc < 1) {
    Tcl_AppendResult(interp, "Usage radial_profile id $ids center $x $y $z maxr $r_max nbins $n\n" , (char *)NULL);
    return TCL_ERROR;
  }
  while (argc>0) {
    if (ARG0_IS_S("ids") || ARG0_IS_S("types") || ARG0_IS_S("all")) {
      if (!parse_id_list(interp, argc, argv, &temp, &pdata->id_list )==TCL_OK) {
        Tcl_AppendResult(interp, "Error reading profile: Error parsing particle id information\n" , (char *)NULL);
        return TCL_ERROR;
      } else {
        *change+=temp;
        argc-=temp;
        argv+=temp;
      }
    } else if ( ARG0_IS_S("center")){
      if (argc>3 && ARG1_IS_D(pdata->center[0]) && ARG_IS_D(2,pdata->center[1]) && ARG_IS_D(3,pdata->center[2])) {
        argc-=4;
        argv+=4;
        *change+=4;
      } else {
        Tcl_AppendResult(interp, "Error in radial_profile: could not read center\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if ( ARG0_IS_S("axis")){
        Tcl_AppendResult(interp, "Using arbitrary axes does not work yet!\n" , (char *)NULL);
        return TCL_ERROR;
      if (argc>3 && ARG1_IS_D(pdata->axis[0]) && ARG_IS_D(2,pdata->axis[1]) && ARG_IS_D(3,pdata->axis[2])) {
        argc-=4;
        argv+=4;
        *change+=4;
      } else {
        Tcl_AppendResult(interp, "Error in radial_profile: could not read center\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if  ( ARG0_IS_S("maxr") ) {
      if (argc>1 && ARG1_IS_D(pdata->maxr)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in radial_profile: could not read maxr\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if  ( ARG0_IS_S("minr") ) {
      if (argc>1 && ARG1_IS_D(pdata->maxr)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in radial_profile: could not read maxr\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if ( ARG0_IS_S("minz")){
      if (argc>1 && ARG1_IS_D(pdata->minz)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read minz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if ( ARG0_IS_S("maxz") ) {
      if (argc>1 && ARG1_IS_D(pdata->maxz)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read maxz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if ( ARG0_IS_S("minphi")){
      if (argc>1 && ARG1_IS_D(pdata->minphi)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read minz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if ( ARG0_IS_S("maxphi") ) {
      if (argc>1 && ARG1_IS_D(pdata->maxphi)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in profile: could not read maxz\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if (ARG0_IS_S("rbins")) {
      if (argc>1 && ARG1_IS_I(pdata->rbins)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in radial_profile: could not read rbins\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if (ARG0_IS_S("zbins")) {
      if (argc>1 && ARG1_IS_I(pdata->zbins)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in radial_profile: could not read rbins\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else if (ARG0_IS_S("phibins")) {
      if (argc>1 && ARG1_IS_I(pdata->phibins)) {
        argc-=2;
        argv+=2;
        *change+=2;
      } else {
        Tcl_AppendResult(interp, "Error in radial_profile: could not read rbins\n" , (char *)NULL);
        return TCL_ERROR;
      } 
    } else {
      Tcl_AppendResult(interp, "Error in radial_profile: understand argument ", argv[0], "\n" , (char *)NULL);
      return TCL_ERROR;
    }
  }
  
  temp=0;
//  if (pdata->center[0]>1e90) {
//    Tcl_AppendResult(interp, "Error in radial_profile: center not specified\n" , (char *)NULL);
//    temp=1;
//  }
//  if (pdata->maxr>1e90) {
//    Tcl_AppendResult(interp, "Error in radial_profile: maxr not specified\n" , (char *)NULL);
//    temp=1;
//  }
//  if (pdata->rbins<1) {
//    Tcl_AppendResult(interp, "Error in radial_profile: rbins not specified\n" , (char *)NULL);
//    temp=1;
//  }
  if (temp)
    return TCL_ERROR;
  else
    return TCL_OK;
}