Beispiel #1
0
particle *MakeParticle(particle *P, REAL ENE, REAL ANG, REAL AZI, unsigned int *seed) {
    REAL	angle, azimuth;
    P->type = PROTON;
    P->energy = ENE;
    angle = ANG * M_PI / AS_REAL(180.0);
    azimuth = AZI * M_PI / AS_REAL(180.0);
    position_particle(azimuth, angle, P);
#if DO_ELASTIC
    GenerateElasticDistances(P, seed);
#endif
#if MIN_TRACE
    P->eloss = AS_REAL(0.0);
    P->where = WhereAmI(P->pos[CX], P->pos[CY], P->pos[CZ]);
#endif
#if GOM_DEBUG
    if (VERBOSE) {
	print_particle("Made particle:", P);
    }
#endif
    return(P);
}
Beispiel #2
0
void MonteCarlo(collector *C, int NMC, REAL emean, REAL estdv, REAL sigma, REAL angle, REAL azimuth) {
    particle	    *P;
    trace	    *T;
    int		    NF;
    unsigned int seed;
    NF = 0;
#if DEBUG
    printf("entering MonteCarlo for %d samples and storing into %lx (%d)\n",
	   NMC, (long unsigned int) C, C->NTOTAL);
#endif
/* create the trace and particle */
    fast_srand(&seed);
    T = alloc_trace();
    P = (particle *) malloc(sizeof(particle));
/* the Monte Carlo loop */
//what is sigma??
    if (sigma > AS_REAL(0.0)) {
	while (NF++ < NMC) {
	    MakeParticle(P, normal(emean, estdv,&seed), angle+normal(AS_REAL(0.0), sigma,&seed), azimuth+normal(AS_REAL(0.0), sigma,&seed), &seed);
	    reset_trace(T);
	    while (P->energy > AS_REAL(0.0)) {
		proton_event(P, T, &seed); //stepping()
	    }
	    if (TRACE) dump_trace(stdout, T, P);
	    collect(C, P, T); //Hits collection
	}
    } else {
	while (NF++ < NMC) {
	    MakeParticle(P, normal(emean, estdv,&seed), angle, azimuth, &seed);
	    reset_trace(T);
	    while (P->energy > AS_REAL(0.0)) {
		proton_event(P, T, &seed);
	    }
	    if (TRACE) dump_trace(stdout, T, P);
	    collect(C, P, T);
	}
    }
}
Beispiel #3
0
void position_particle(ANGLE phi, ANGLE theta, particle *P) {
    int			i;
    POSITION		A[3], B[3], C[3], xy, d1, d2, dx, dy, dz;
    enum plane_type	S[3];
/* A is the center */
    A[CX] = ARENA->CEN[CX];
    A[CY] = ARENA->CEN[CY];
    A[CZ] = ARENA->CEN[CZ];
/* B is a point with phi/theta at Radius */
    xy = ARENA->RADIUS * SIN(phi);
    B[CX] = A[CX] + xy * COS(theta);
    B[CY] = A[CY] + xy * SIN(theta);
    B[CZ] = A[CZ] + ARENA->RADIUS * COS(phi);
/* check */
    assert(inside(A));
    assert(! inside(B));
#if GOM_DEBUG
    printf("entering position particle: phi=%7.3f theta=%7.3f\n\tA=(%7.3f,%7.3f,%7.3f) B=(%7.3f,%7.3f,%7.3f)\n",
	   phi, theta, A[CX], A[CY], A[CZ], B[CX], B[CY], B[CZ]);
#endif
/* loop for NITER times */
    for (i=0; i<NITER; i++) {
	C[CX] = AS_REAL(0.5)*(A[CX] + B[CX]);
	C[CY] = AS_REAL(0.5)*(A[CY] + B[CY]);
	C[CZ] = AS_REAL(0.5)*(A[CZ] + B[CZ]);
	if (inside(C)) {
	    A[CX] = C[CX]; A[CY] = C[CY]; A[CZ] = C[CZ];
	} else {
	    B[CX] = C[CX]; B[CY] = C[CY]; B[CZ] = C[CZ];
	}
    }
#if GOM_DEBUG
    printf("after binary search C: %7.3f %7.3f %7.3f\n", C[CX], C[CY], C[CZ]);
#endif
/* calculate distances to nearest plane in X/Y/Z */
    d1 = ABS(A[CX]-ARENA->MIN[CX]); d2 = ABS(A[CX]-ARENA->MAX[CX]);
    if (d1 < d2) { dx = d1; S[CX] = WEST; } else { dx = d2; S[CX] = EAST; }
    d1 = ABS(A[CY]-ARENA->MIN[CY]); d2 = ABS(A[CY]-ARENA->MAX[CY]);
    if (d1 < d2) { dy = d1; S[CY] = NORTH; } else { dy = d2; S[CY] = SOUTH; }
    d1 = ABS(A[CZ]-ARENA->MIN[CZ]); d2 = ABS(A[CZ]-ARENA->MAX[CZ]);
    if (d1 < d2) { dz = d1; S[CZ] = BOTTOM; } else { dz = d2; S[CZ] = TOP; }
#if GOM_DEBUG
    printf("distances: %7.3f %s %7.3f %s %7.3f %s\n",
	    dx, plane_name[(int) S[CX]], dy, plane_name[(int) S[CY]], dz, plane_name[(int) S[CZ]]);
#endif
/* find the closest one and snap the appropriate coordinate */
    if (dx <= dy) {
	if (dx <= dz) {
	    C[CX] = (S[CX] == WEST ? ARENA->MIN[CX] : ARENA->MAX[CX]);
	} else {
	    C[CZ] = (S[CZ] == BOTTOM ? ARENA->MIN[CZ] : ARENA->MAX[CZ]);
	}
    } else {
	if (dy <= dz) {
	    C[CY] = (S[CY] == NORTH ? ARENA->MIN[CY] : ARENA->MAX[CY]);
	} else {
	    C[CZ] = (S[CZ] == BOTTOM ? ARENA->MIN[CZ] : ARENA->MAX[CZ]);
	}
    }
    P->pos[CX] = C[CX]; P->pos[CY] = C[CY]; P->pos[CZ] = C[CZ];
    C[CX] -= ARENA->CEN[CX];
    C[CY] -= ARENA->CEN[CY];
    C[CZ] -= ARENA->CEN[CZ];
    d1 = SQRT(C[CX]*C[CX] + C[CY]*C[CY] + C[CZ]*C[CZ]);
    P->dir[CX] = -C[CX]/d1; P->dir[CY] = -C[CY]/d1; P->dir[CZ] = -C[CZ]/d1;
#if GOM_DEBUG
    printf("final C: %7.3f %7.3f %7.3f -> %7.3f %7.3f %7.3f\n", P->pos[CX], P->pos[CY], P->pos[CZ], P->dir[CX], P->dir[CY], P->dir[CZ]);
#endif
}
Beispiel #4
0
/* intialize path to MRI file */
char *MRIFIL = NULL;
/* intialize path to LOCATION (0/1) file */
char *LOCFIL = NULL;
/* intialize path to binary output file */
char *BOUTFIL = NULL;
/* intialize path to text output file */
char *TOUTFIL = NULL;
/* verbosity switch */
int VERBOSE = 1;
/* trace switch */
int TRACE = 0;
/* the geometry */
arena* ARENA = NULL;
/* MRI voxel size */
REAL PIXEL = AS_REAL(0.0);
/* threshold for dumping voxels (proportion of maximum)  */
REAL THR = AS_REAL(0.01);
/* this describes the options */
ParamDescriptor _params[] = {
/*	name		type		dflt		mandatory   */
    {   "nmc",		P_INTEGER,	"10000",		0,	    },
    {   "mean",		P_REAL,		"100",		0,	    },	    /* 100MeV */
    {   "stdv",		P_REAL,		"2",		0,	    },	    /* 2MeV */
    {   "sigma",	P_REAL,		"0.01",		0,	    },	    /* initial postion sigma */
    {   "path",		P_PATH,		"./tables",	0,	    },	    /* path to where the tables are */
    {   "mri",		P_READ,		0,		0,	    },	    /* path to an MRI cube file */
    {   "trace",	P_FLAG,		"0",		0,	    },	    /* generate traces? */
    {   "plot",		P_FLAG,		"0",		0,	    },	    /* make plot file? */
    {   "angle",	P_REAL,		"0.0",		0,	    },	    /* angle in XY plane */
    {   "azimuth",	P_REAL,		"90.0",		0,	    },	    /* angle to Z axis */
Beispiel #5
0
void execute_function(VM *vm) {
restart: {
    Frame *frame = vm->current;
    Closure *closure = frame->closure;
    Chunk *chunk = closure->chunk;
    StackObject *registers = frame->registers;

    while (frame->pc < chunk->numinstructions) {
        int instruction = chunk->instructions[frame->pc];

        OpCode o = GET_O(instruction);
        int a = GET_A(instruction);
        int b = GET_B(instruction);
        int c = GET_C(instruction);

        switch (o) {
            case OP_MOVE:
            {
                if (b < 256) {
                    copy_object(&registers[a], &registers[b]);
                } else {
                    copy_constant(vm, &registers[a], chunk->constants[b - 256]);
                }
            } break;

            case OP_GETUPVAR:
            {
                Upval *upval = closure->upvals[b];

                if (!upval->open) {
                    // upval is closed
                    copy_object(&registers[a], upval->data.o);
                } else {
                    // still on stack
                    copy_object(&registers[a], &upval->data.ref.frame->registers[upval->data.ref.slot]);
                }
            } break;

            case OP_SETUPVAR:
            {
                Upval *upval = closure->upvals[b];

                if (!upval->open) {
                    // upval is closed
                    copy_object(upval->data.o, &registers[a]);
                } else {
                    // still on stack
                    copy_object(&upval->data.ref.frame->registers[upval->data.ref.slot], &registers[a]);
                }
            } break;

            case OP_ADD:
            {
                // TODO - make string coercion better
                // TODO - make string type with special operators

                if (IS_STR(b) || IS_STR(c)) {
                    char *arg1 = TO_STR(b);
                    char *arg2 = TO_STR(c);

                    char *arg3 = malloc((strlen(arg1) + strlen(arg2) + 1) + sizeof *arg3);

                    strcpy(arg3, arg1);
                    strcat(arg3, arg2);

                    registers[a].value.o = make_string_ref(vm, arg3);
                    registers[a].type = OBJECT_REFERENCE; // put this after

                    free(arg1);
                    free(arg2);
                } else {
                    if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                        fatal("Cannot add types.");
                    }

                    if (IS_INT(b) && IS_INT(c)) {
                        int arg1 = AS_INT(b);
                        int arg2 = AS_INT(c);

                        registers[a].type = OBJECT_INT;
                        registers[a].value.i = arg1 + arg2;
                    } else {
                        double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                        double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                        registers[a].type = OBJECT_REAL;
                        registers[a].value.d = arg1 + arg2;
                    }
                }
            } break;

            case OP_SUB:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to sub non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 - arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 - arg2;
                }
            } break;

            case OP_MUL:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to mul non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 * arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 * arg2;
                }
            } break;

            case OP_DIV:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if ((IS_INT(c) && AS_INT(c) == 0) || (IS_REAL(c) && AS_REAL(c) == 0)) {
                    fatal("Div by 0.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 / arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 / arg2;
                }
            } break;

            case OP_MOD:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if ((IS_INT(c) && AS_INT(c) == 0) || (IS_REAL(c) && AS_REAL(c) == 0)) {
                    fatal("Mod by 0.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 % arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.i = fmod(arg1, arg2);
                }
            } break;

            case OP_POW:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = (int) pow(arg1, arg2);
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = pow(arg1, arg2);
                }
            } break;

            case OP_NEG:
            {
                if (IS_INT(b)) {
                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = -AS_INT(b);
                } else if (IS_REAL(b)) {
                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = -AS_REAL(b);
                } else {
                    fatal("Tried to negate non-numeric type.");
                }
            } break;

            case OP_NOT:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                registers[a].value.i = registers[a].value.i == 1 ? 0 : 1;
            } break;

            case OP_EQ:
            {
                if ((IS_INT(b) || IS_REAL(b)) && (IS_INT(c) || IS_REAL(c))) {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_BOOL;
                    registers[a].value.i = arg1 == arg2;
                } else {
                    fatal("Comparison of reference types not yet supported.");
                }
            } break;

            case OP_LT:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to compare non-numbers.");
                }

                double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                registers[a].type = OBJECT_BOOL;
                registers[a].value.i = arg1 < arg2;
            } break;

            case OP_LE:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to compare non-numbers.");
                }

                double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                registers[a].type = OBJECT_BOOL;
                registers[a].value.i = arg1 <= arg2;
            } break;

            case OP_CLOSURE:
            {
                Closure *child = make_closure(chunk->children[b]);

                int i;
                for (i = 0; i < chunk->children[b]->numupvars; i++) {
                    int inst = chunk->instructions[++frame->pc];

                    OpCode oc = GET_O(inst);
                    int ac = GET_A(inst);
                    int bc = GET_B(inst);
                    int cc = GET_C(inst);

                    if (oc == OP_MOVE) {
                        // first upval for this variable
                        child->upvals[ac] = make_upval(vm, bc);
                    } else {
                        // share upval
                        child->upvals[ac] = closure->upvals[bc];
                        child->upvals[ac]->refcount++;
                    }
                }

                registers[a].value.o = make_closure_ref(vm, child);
                registers[a].type = OBJECT_REFERENCE; // put this after
            } break;

            case OP_CALL:
            {
                if (registers[b].type != OBJECT_REFERENCE || registers[b].value.o->type != OBJECT_CLOSURE) {
                    fatal("Tried to call non-closure.");
                }

                // TODO - safety issue (see compile.c for notes)

                Closure *child = registers[b].value.o->value.c;
                Frame *subframe = make_frame(frame, child);

                int i;
                for (i = 0; i < child->chunk->numparams; i++) {
                    copy_object(&subframe->registers[i + 1], &registers[c + i]);
                }

                vm->current = subframe;
                goto restart;
            } break;

            case OP_RETURN:
            {
                UpvalNode *head;
                for (head = vm->open; head != NULL; ) {
                    Upval *u = head->upval;

                    if (u->data.ref.frame == frame) {
                        StackObject *o = malloc(sizeof *o);

                        if (!o) {
                            fatal("Out of memory.");
                        }

                        u->open = 0;
                        copy_object(o, &registers[u->data.ref.slot]);
                        u->data.o = o;

                        if (vm->open == head) {
                            vm->open = head->next;
                        } else {
                            head->next->prev = head->prev;
                            head->prev->next = head->next;
                        }

                        UpvalNode *temp = head;
                        head = head->next;
                        free(temp);
                    } else {
                        head = head->next;
                    }
                }

                if (vm->current->parent != NULL) {
                    Frame *p = vm->current->parent;
                    StackObject *target = &p->registers[GET_A(p->closure->chunk->instructions[p->pc++])];

                    if (b < 256) {
                        // debug
                        char *d = obj_to_str(&registers[b]);
                        printf("Return value: %s\n", d);
                        free(d);

                        copy_object(target, &registers[b]);
                    } else {
                        copy_constant(vm, target, chunk->constants[b - 256]);
                    }

                    free_frame(frame);

                    vm->current = p;
                    goto restart;
                } else {
                    // debug
                    char *d = obj_to_str(&registers[b]);
                    printf("Return value: %s\n", d);
                    free(d);

                    free_frame(frame);
                    vm->current = NULL;
                    return;
                }
            } break;

            case OP_JUMP:
                frame->pc += c ? -b : b;
                break;

            case OP_JUMP_TRUE:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                if (registers[a].value.i == 1) {
                    frame->pc += c ? -b : b;
                }
            } break;

            case OP_JUMP_FALSE:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                if (registers[a].value.i == 0) {
                    frame->pc += c ? -b : b;
                }
            } break;

            case OP_ENTER_TRY:
            {
                vm->catchframe = make_catch_frame(frame, vm->catchframe, frame->pc + b);
            } break;

            case OP_LEAVE_TRY:
            {
                CatchFrame *temp = vm->catchframe;
                vm->catchframe = vm->catchframe->parent;
                free_catch_frame(temp);
            } break;

            case OP_THROW:
            {
                // TODO - replace unwinding of stack with an exceptions
                // table per-chunk. It will have an instructions range,
                // the starting instruction of a handler, and the type of
                // exception that it may handle.

                // Exception table:
                // From    To      Target      Type
                // 0       4       5           Class TestExc1
                // 0       12      12          Class TestExc2

                // TODO - implement a way to expect an exception
                // of a given type instead of a generic catch-all.

                char *s = obj_to_str(&registers[a]);
                printf("Exception value: %s!\n", s);
                free(s);

                // TODO - this is probably wrong. Not sure how complicated
                // it will be to handle upvalues and frame destruction here,
                // so we're just doing it a shitty way for now :D [GO LAZE].

                if (!vm->catchframe) {
                    // TODO - print a stack trace [ requires debug symbols :( ]
                    fatal("Exception thrown outside of handler.");
                }

                while (vm->current != vm->catchframe->frame) {
                    // TODO - destruct frame
                    vm->current = vm->current->parent;
                }

                vm->current->pc = vm->catchframe->target;

                CatchFrame *temp = vm->catchframe;
                vm->catchframe = vm->catchframe->parent;
                free_catch_frame(temp);

                goto restart;
            } break;
        }

        frame->pc++;
    }

    fatal("VM left instruction-space.");
}
}