Skip to content

Commit

Permalink
python diff
Browse files Browse the repository at this point in the history
  • Loading branch information
hannorein committed Aug 26, 2023
1 parent 7fa5a80 commit 031bbe4
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 24 deletions.
4 changes: 3 additions & 1 deletion rebound/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,9 @@ def status(self, showParticles=True, showAllFields=True):
if showAllFields:
print("The following fields have non-default values:")
newsim = Simulation()
clibrebound.reb_diff_simulations(byref(newsim), byref(self),c_int(1))
clibrebound.reb_diff_simulations_char.restype = c_char_p
output = clibrebound.reb_diff_simulations_char(byref(newsim), byref(self))
print(output.decode("utf-8"))



Expand Down
105 changes: 82 additions & 23 deletions src/binarydiff.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,33 +87,41 @@ const struct reb_binary_field_descriptor reb_binary_field_descriptor_for_name(co
return bfd;
}

void print_reb_type(FILE * restrict stream, int dtype, char* pointer, size_t size){
static void output_stream_reb_type(int dtype, char* pointer, size_t dsize, char** buf){
char* newbuf = NULL;
switch (dtype){
case REB_DOUBLE:
fprintf(stream, "%e",*(double*)(pointer));
asprintf(&newbuf,"%e",*(double*)(pointer));
break;
case REB_INT:
fprintf(stream, "%d",*(int*)(pointer));
asprintf(&newbuf,"%d",*(int*)(pointer));
break;
case REB_UINT:
fprintf(stream, "%u",*(unsigned int*)(pointer));
asprintf(&newbuf,"%u",*(unsigned int*)(pointer));
break;
case REB_UINT32:
fprintf(stream, "%"PRIu32,*(uint32_t*)(pointer)); // PRIu32 defined in inttypes.h
asprintf(&newbuf,"%"PRIu32,*(uint32_t*)(pointer)); // PRIu32 defined in inttypes.h
break;
case REB_LONG:
fprintf(stream, "%ld",*(long*)(pointer));
asprintf(&newbuf,"%ld",*(long*)(pointer));
break;
case REB_ULONG:
fprintf(stream, "%lu",*(unsigned long*)(pointer));
asprintf(&newbuf,"%lu",*(unsigned long*)(pointer));
break;
case REB_ULONGLONG:
fprintf(stream, "%llu",*(unsigned long long*)(pointer));
asprintf(&newbuf,"%llu",*(unsigned long long*)(pointer));
break;
default:
fprintf(stream, "(%zu bytes, values not printed)", size);
asprintf(&newbuf,"(%zu bytes, values not printed)", dsize);
break;
}
if (buf){
*buf = realloc(*buf, strlen(*buf) + strlen(newbuf) + sizeof(char));
strcat(*buf,newbuf);
}else{
printf("%s",newbuf);
}
free(newbuf);
}

int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t size2, char** bufp, size_t* sizep, int output_option){
Expand All @@ -128,6 +136,10 @@ int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t si
*bufp = NULL;
*sizep = 0;
}
if (output_option==3){
*bufp = malloc(sizeof(char));
*bufp[0] = '\0';
}
size_t allocatedsize = 0;

// Header.
Expand Down Expand Up @@ -181,11 +193,26 @@ int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t si
are_different = 1.;
if (output_option==0){
reb_output_stream_write(bufp, &allocatedsize, sizep, &field1,sizeof(struct reb_binary_field));
}else if (output_option==1){
}else if (output_option==1 || output_option==3){
const struct reb_binary_field_descriptor fd = reb_binary_field_descriptor_for_type(field1.type);
printf("%s:\n\033[31m< ",fd.name);
print_reb_type(stdout, fd.dtype, buf1+pos1, field1.size);
printf("\033[0m\n");
char* buf;
asprintf(&buf, "%s:\n\033[31m< ",fd.name);
if (bufp){
*bufp = realloc(*bufp, strlen(*bufp) + strlen(buf) + sizeof(char));
strcat(*bufp,buf);
}else{
printf("%s",buf);
}
free(buf);
output_stream_reb_type(fd.dtype, buf1+pos1, field1.size, bufp);
asprintf(&buf, "\033[0m\n");
if (bufp){
*bufp = realloc(*bufp, strlen(*bufp) + strlen(buf) + sizeof(char));
strcat(*bufp,buf);
}else{
printf("%s",buf);
}
free(buf);
}
field1.size = 0;
continue;
Expand Down Expand Up @@ -219,13 +246,32 @@ int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t si
if (output_option==0){
reb_output_stream_write(bufp, &allocatedsize, sizep, &field2,sizeof(struct reb_binary_field));
reb_output_stream_write(bufp, &allocatedsize, sizep, buf2+pos2,field2.size);
}else if (output_option==1){
}else if (output_option==1 || output_option==3){
const struct reb_binary_field_descriptor fd = reb_binary_field_descriptor_for_type(field1.type);
printf("%s:\n\033[31m< ",fd.name);
print_reb_type(stdout, fd.dtype, buf1+pos1, field1.size);
printf("\033[0m\n---\n\033[32m> ");
print_reb_type(stdout, fd.dtype, buf2+pos2, field2.size);
printf("\033[0m\n");
char* buf;
asprintf(&buf, "%s:\n\033[31m< ",fd.name);
if (bufp){
*bufp = realloc(*bufp, strlen(*bufp) + strlen(buf) + sizeof(char));
strcat(*bufp,buf);
}else{
printf("%s",buf);
}
output_stream_reb_type(fd.dtype, buf1+pos1, field1.size, bufp);
asprintf(&buf, "\033[0m\n---\n\033[32m> ");
if (bufp){
*bufp = realloc(*bufp, strlen(*bufp) + strlen(buf) + sizeof(char));
strcat(*bufp,buf);
}else{
printf("%s",buf);
}
output_stream_reb_type(fd.dtype, buf2+pos2, field2.size, bufp);
asprintf(&buf, "\033[0m\n");
if (bufp){
*bufp = realloc(*bufp, strlen(*bufp) + strlen(buf) + sizeof(char));
strcat(*bufp,buf);
}else{
printf("%s",buf);
}
}
}
pos1 += field1.size;
Expand Down Expand Up @@ -284,11 +330,24 @@ int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t si
if (output_option==0){
reb_output_stream_write(bufp, &allocatedsize, sizep, &field2,sizeof(struct reb_binary_field));
reb_output_stream_write(bufp, &allocatedsize, sizep, buf2+pos2,field2.size);
}else if (output_option==1){
}else if (output_option==1 || output_option==3){
const struct reb_binary_field_descriptor fd = reb_binary_field_descriptor_for_type(field2.type);
printf("%s:\n\033[32m> ",fd.name);
print_reb_type(stdout, fd.dtype, buf2+pos2, field2.size);
printf("\033[0m\n");
char* buf;
asprintf(&buf, "%s:\n\033[32m> ",fd.name);
if (bufp){
*bufp = realloc(*bufp, strlen(*bufp) + strlen(buf) + sizeof(char));
strcat(*bufp,buf);
}else{
printf("%s",buf);
}
output_stream_reb_type(fd.dtype, buf2+pos2, field2.size, bufp);
asprintf(&buf, "\033[0m\n");
if (bufp){
*bufp = realloc(*bufp, strlen(*bufp) + strlen(buf) + sizeof(char));
strcat(*bufp,buf);
}else{
printf("%s",buf);
}
}
pos1 = 64;
pos2 += field2.size;
Expand Down
15 changes: 15 additions & 0 deletions src/rebound.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,21 @@ void reb_copy_simulation_with_messages(struct reb_simulation* r_copy, struct re

}

char* reb_diff_simulations_char(struct reb_simulation* r1, struct reb_simulation* r2){
char* bufp1;
char* bufp2;
char* bufp;
size_t sizep1, sizep2, size;
reb_output_binary_to_stream(r1, &bufp1,&sizep1);
reb_output_binary_to_stream(r2, &bufp2,&sizep2);

reb_binary_diff_with_options(bufp1, sizep1, bufp2, sizep2, &bufp, &size, 3);

free(bufp1);
free(bufp2);
return bufp;
}

int reb_diff_simulations(struct reb_simulation* r1, struct reb_simulation* r2, int output_option){
if (output_option!=1 && output_option!=2){
// Not implemented
Expand Down
3 changes: 3 additions & 0 deletions src/rebound.h
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,8 @@ void reb_stop(struct reb_simulation* const r); // Stop current integration
// If r1 and r2 are exactly equal to each other then 0 is returned, otherwise 1. Walltime is ignored.
// If output_option=1, then output is printed on the screen. If 2, only return value os given.
int reb_diff_simulations(struct reb_simulation* r1, struct reb_simulation* r2, int output_option);
// Same but return value is string to human readable difference. Needs to be freed.
char* reb_diff_simulations_char(struct reb_simulation* r1, struct reb_simulation* r2);

// Mercurius switching functions
double reb_integrator_mercurius_L_mercury(const struct reb_simulation* const r, double d, double dcrit);
Expand Down Expand Up @@ -916,6 +918,7 @@ void reb_binary_diff(char* buf1, size_t size1, char* buf2, size_t size2, char**
// - If set to 0, differences are written to bufp in the form of reb_binary_field structs.
// - If set to 1, differences are printed on the screen.
// - If set to 2, only the return value indicates any differences.
// - If set to 3, differences are written to bufp in a human readable form.
// returns value: 0 is returned if the simulations do not differ (are equal). 1 is return if they differ.
int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t size2, char** bufp, size_t* sizep, int output_option);
// Returns the name fora given binary field type or name
Expand Down

0 comments on commit 031bbe4

Please sign in to comment.