xboa
Hitcore.c
Go to the documentation of this file.
1 //This file is a part of xboa
2 //
3 //xboa is free software: you can redistribute it and/or modify
4 //it under the terms of the GNU General Public License as published by
5 //the Free Software Foundation, either version 3 of the License, or
6 //(at your option) any later version.
7 //
8 //xboa is distributed in the hope that it will be useful,
9 //but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 //GNU General Public License for more details.
12 //
13 //You should have received a copy of the GNU General Public License
14 //along with xboa in the doc folder. If not, see
15 //<http://www.gnu.org/licenses/>.
16 //
17 
18 
19 #include <Python.h>
20 #include <structmember.h>
21 #include <string.h>
22 #include <stdio.h>
23 
24 #define Hitcore_c 1
25 #include "Hitcore.h"
26 
27 /////// GLOBAL HITCORE DATA /////////
28 //Globals for C stuff
29 //Python stuff defined later
30 
31 //hybrid - global_weights will always have one value for each event so that it can do random access
32 PyObject* global_weight_table = NULL;
33 
34 //list that converts between variable names and get function pointers
35 typedef struct {const char* variable; hc_get_dbl_function get_func;} __hc_get_dbl_function;
36 int n_get_dbl_variables = 0; //set in hitcore_init
37 static __hc_get_dbl_function hc_get_dbl_function_list[] = {
38 {"x", hc_get_x},
39 {"y", hc_get_y},
40 {"z", hc_get_z},
41 {"t", hc_get_t},
42 {"px", hc_get_px},
43 {"py", hc_get_py},
44 {"pz", hc_get_pz},
45 {"energy", hc_get_energy},
46 {"mass", hc_get_mass},
47 {"local_weight", hc_get_local_weight},
48 {"global_weight", hc_get_global_weight},
49 {"weight", hc_get_total_weight},
50 {"bx", hc_get_bx},
51 {"by", hc_get_by},
52 {"bz", hc_get_bz},
53 {"ex", hc_get_ex},
54 {"ey", hc_get_ey},
55 {"ez", hc_get_ez},
56 {"sx", hc_get_sx},
57 {"sy", hc_get_sy},
58 {"sz", hc_get_sz},
59 {"path_length", hc_get_pl},
60 {"proper_time", hc_get_tau},
61 {"e_dep", hc_get_e_dep},
62 {"charge", hc_get_charge},
63 {NULL, NULL},
64 };
65 
66 
67 //list that converts between variable names and set function pointers
68 typedef struct {char* variable; hc_set_dbl_function set_func;} __hc_set_dbl_function;
69 int n_set_dbl_variables = 0; //set in hitcore_init
70 static __hc_set_dbl_function hc_set_dbl_function_list[] = {
71 {"x", hc_set_x},
72 {"y", hc_set_y},
73 {"z", hc_set_z},
74 {"t", hc_set_t},
75 {"px", hc_set_px},
76 {"py", hc_set_py},
77 {"pz", hc_set_pz},
78 {"energy", hc_set_energy},
79 {"mass", hc_set_mass},
80 {"local_weight", hc_set_local_weight},
81 {"global_weight", hc_set_global_weight},
82 {"bx", hc_set_bx},
83 {"by", hc_set_by},
84 {"bz", hc_set_bz},
85 {"ex", hc_set_ex},
86 {"ey", hc_set_ey},
87 {"ez", hc_set_ez},
88 {"sx", hc_set_sx},
89 {"sy", hc_set_sy},
90 {"sz", hc_set_sz},
91 {"path_length", hc_set_pl},
92 {"proper_time", hc_set_tau},
93 {"e_dep", hc_set_e_dep},
94 {"charge", hc_set_charge},
95 {NULL, NULL},
96 };
97 
98 typedef struct {const char* variable; hc_get_int_function get_func;} __hc_get_int_function;
99 int n_get_int_variables = 0; //set in hitcore_init
100 static __hc_get_int_function hc_get_int_function_list[] = {
101 {"event_number",hc_get_event_number},
102 {"station", hc_get_station},
103 {"pid", hc_get_pid},
104 {"status", hc_get_status},
105 {"spill", hc_get_spill},
106 {"particle_number", hc_get_particle_number},
107 {"eventNumber", hc_get_event_number},
108 {"particleNumber", hc_get_particle_number},
109 {NULL,NULL},
110 };
111 
112 typedef struct {const char* variable; hc_set_int_function set_func;} __hc_set_int_function;
113 int n_set_int_variables = 0; //set in hitcore_init
114 static __hc_set_int_function hc_set_int_function_list[] = {
115 {"event_number",hc_set_event_number},
116 {"station", hc_set_station},
117 {"pid", hc_set_pid},
118 {"status", hc_set_status},
119 {"spill", hc_set_spill},
120 {"particle_number", hc_set_particle_number},
121 {"eventNumber", hc_set_event_number},
122 {"particleNumber", hc_set_particle_number},
123 {NULL,NULL},
124 };
125 
126 static void hc_Hitcore_dealloc(Hitcore * self)
127 {
128  hc_Hitcore_free(self);
129 }
130 
131 static void hc_Hitcore_free(Hitcore * self)
132 {
133  if (self != NULL)
134  free(self);
135 }
136 
137 static PyObject* hc_Hitcore_alloc(PyTypeObject *type, Py_ssize_t nitems)
138 {
139  Hitcore* hc = malloc(sizeof(Hitcore));
140  hc->ob_refcnt = 1;
141  hc->ob_type = type;
142  return (PyObject*)hc;
143 }
144 
145 static PyObject* hc_Hitcore_new(PyTypeObject *type, Py_ssize_t nitems)
146 {
147  Hitcore* hc = (Hitcore*)hc_Hitcore_alloc(type, nitems);
148  hc->x = 0.;
149  hc->y = 0.;
150  hc->z = 0.;
151  hc->t = 0.;
152  hc->px = 0.;
153  hc->py = 0.;
154  hc->pz = 0.;
155  hc->energy = 0.;
156  hc->mass = 0.;
157  hc->weight = 1.;
158  hc->bx = 0.;
159  hc->by = 0.;
160  hc->bz = 0.;
161  hc->ex = 0.;
162  hc->ey = 0.;
163  hc->ez = 0.;
164  hc->sx = 0.;
165  hc->sy = 0.;
166  hc->sz = 0.;
167  hc->pl = 0.;
168  hc->tau = 0.;
169  hc->e_dep = 0.;
170  hc->charge = 0.;
171 
172  hc->spill = 0;
173  hc->event = 0;
174  hc->station = 0;
175  hc->pid = 0;
176  hc->particle = 0;
177  hc->status = 0;
178 
179  return (PyObject*)hc;
180 }
181 
182 static int hc_Hitcore_init(PyObject* self, PyObject *args, PyObject *kwds)
183 {
184 
185  Hitcore* hc = (Hitcore*)self;
186  hc->x = 0.;
187  hc->y = 0.;
188  hc->z = 0.;
189  hc->t = 0.;
190  hc->px = 0.;
191  hc->py = 0.;
192  hc->pz = 0.;
193  hc->energy = 0.;
194  hc->mass = 0.;
195  hc->weight = 1.;
196  hc->bx = 0.;
197  hc->by = 0.;
198  hc->bz = 0.;
199  hc->ex = 0.;
200  hc->ey = 0.;
201  hc->ez = 0.;
202  hc->sx = 0.;
203  hc->sy = 0.;
204  hc->sz = 0.;
205  hc->pl = 0.;
206  hc->tau = 0.;
207  hc->e_dep = 0.;
208  hc->charge = 0.;
209 
210  hc->spill = 0;
211  hc->event = 0;
212  hc->station = 0;
213  hc->pid = 0;
214  hc->particle = 0;
215  hc->status = 0;
216  return 0;
217 }
218 
219 ////// GET METHODS ///////
220 //specialist get_methods
221 double hc_get_x(Hitcore* self) {return self->x;}
222 double hc_get_y(Hitcore* self) {return self->y;}
223 double hc_get_z(Hitcore* self) {return self->z;}
224 double hc_get_t(Hitcore* self) {return self->t;}
225 double hc_get_px(Hitcore* self) {return self->px;}
226 double hc_get_py(Hitcore* self) {return self->py;}
227 double hc_get_pz(Hitcore* self) {return self->pz;}
228 double hc_get_energy(Hitcore* self) {return self->energy;}
229 
231 double hc_get_local_weight (Hitcore* self) {return self->weight;}
232 double hc_get_mass(Hitcore* self) {return self->mass;}
233 double hc_get_bx(Hitcore* self) {return self->bx;}
234 double hc_get_by(Hitcore* self) {return self->by;}
235 double hc_get_bz(Hitcore* self) {return self->bz;}
236 double hc_get_ex(Hitcore* self) {return self->ex;}
237 double hc_get_ey(Hitcore* self) {return self->ey;}
238 double hc_get_ez(Hitcore* self) {return self->ez;}
239 double hc_get_sx(Hitcore* self) {return self->sx;}
240 double hc_get_sy(Hitcore* self) {return self->sy;}
241 double hc_get_sz(Hitcore* self) {return self->sz;}
242 double hc_get_pl(Hitcore* self) {return self->pl;}
243 double hc_get_tau(Hitcore* self) {return self->tau;}
244 double hc_get_e_dep(Hitcore* self) {return self->e_dep;}
245 double hc_get_charge(Hitcore* self) {return self->charge;}
246 
247 int hc_get_spill (Hitcore* self) {return self->spill;}
248 int hc_get_event_number (Hitcore* self) {return self->event;}
249 int hc_get_station (Hitcore* self) {return self->station;}
250 int hc_get_pid (Hitcore* self) {return self->pid;}
251 int hc_get_status (Hitcore* self) {return self->status;}
252 int hc_get_particle_number(Hitcore* self) {return self->particle;}
253 
254 
255 PyObject* weight_dict_key(Hitcore* self) {
256  int part_num = hc_get_particle_number(self);
257  int spill = hc_get_spill(self);
258  int event_num = hc_get_event_number(self);
259  PyObject* key = Py_BuildValue("iii", spill, event_num, part_num);
260  // printf("%i %i %i\n", spill, event_num, part_num);
261  if (key == NULL) { // something went horribly wrong
262  PyErr_SetString(PyExc_TypeError,
263  "Hit spill, event_number or particle_number was not an integer during weight lookup");
264  }
265  return key;
266 }
267 
268 // Optimisation:
269 // 1. avoid the PyArg_ParseTuple call by returning in python
270 // 2. make a hash from spill/event_number/particle_number to a unique id - which
271 // we usually only set on construction. Then use unique id to index weights.
273  double global_weight = 0.;
274  PyObject* key = weight_dict_key(self); // new reference
275  if (key == NULL) { // something went horribly wrong
276  return 1.;
277  }
278  PyObject* value = PyDict_GetItem(global_weight_table, key); // borrowed reference
279  if (value == NULL) {
280  Py_DECREF(key);
281  return 1.; // not set yet - so assume 1.
282  }
283  int err = PyArg_ParseTuple(value, "d", &global_weight);
284  if (err != 1) { // can't handle errors from this function so flee
285  Py_DECREF(key);
286  return 1.;
287  }
288  Py_DECREF(key);
289  return global_weight;
290 }
291 
292 PyObject* hc_get_global_weight_dict(PyObject* self, PyObject* args) {
293  Py_INCREF(global_weight_table);
294  return global_weight_table;
295 }
296 
297 static PyObject* hc_clear_global_weights(PyObject* self, PyObject* args)
298 {
299  PyDict_Clear(global_weight_table);
300  Py_INCREF(Py_None);
301  return Py_None;
302 }
303 
304 //////////////// DOUBLES ////////////////
305 
306 //Get methods that use various types to index the variable in hitcore struct
308 {
309  //for short array a simple loop is probably reasonably quick
310  int i;
311  for(i=0; i<n_get_dbl_variables; i++) {
312  if ( strcmp(hc_get_dbl_function_list[i].variable, variable) == 0 )
313  return hc_get_dbl_function_list[i].get_func;
314  }
315  return NULL;
316 }
317 
318 static double hc_get_dbl_by_string(Hitcore* self, const char* variable, int* ierr)
319 {
320  //for short array a simple loop is probably reasonably quick
322  if(func != NULL) return func(self);
323  *ierr = -1;
324  return 0.;
325 }
326 
327 
328 ////////// INTS ////////////
329 
331 {
332  //for short array a simple loop is probably reasonably quick
333  int i;
334  for(i=0; i<n_get_int_variables; i++)
335  {
336  if ( strcmp(hc_get_int_function_list[i].variable, variable) == 0 )
337  return hc_get_int_function_list[i].get_func;
338  }
339  return NULL;
340 }
341 
342 static int hc_get_int_by_string(Hitcore* self, const char* variable, int* ierr)
343 {
344  //for short array a simple loop is probably reasonably quick
346  if(func != NULL)
347  return func(self);
348  *ierr = -1;
349  return 0.;
350 }
351 
352 ///////// PYTHON INTERFACE /////////
353 
354 static PyObject* hc_get_variables_to_python(PyObject* self, PyObject* args)
355 {
356  int dbl_i=0, int_i=0, j=0;
357  while(hc_get_dbl_function_list[dbl_i].variable != NULL) dbl_i++;
358  while(hc_get_int_function_list[int_i].variable != NULL) int_i++;
359  PyObject* list = PyList_New(dbl_i+int_i);
360  for(j=0; j<dbl_i; j++) PyList_SetItem(list, j, Py_BuildValue("s", hc_get_dbl_function_list[j]));
361  for(j=0; j<int_i; j++) PyList_SetItem(list, j+dbl_i, Py_BuildValue("s", hc_get_int_function_list[j]));
362  return list;
363 }
364 
365 //Get method that python can see
366 static PyObject* hc_get_python(PyObject* self, PyObject* args)
367 {
368  const char* variable_name;
369  int error = 0;
370 
371  //try to turn arg into a string and pass to get_string(var)
372  //I would like to be able to use int argument also (save the array lookup)
373  error = PyArg_ParseTuple(args, "s", &variable_name);
374  if(error != 0)
375  {
376  double value_dbl = hc_get_dbl_by_string((Hitcore*)self, variable_name, &error);
377  if(error >= 0) return Py_BuildValue("d", value_dbl); //return a double
378  error = 0;
379  int value_int = hc_get_int_by_string((Hitcore*)self, variable_name, &error);
380  if(error >= 0) return Py_BuildValue("i", value_int); //return an int
381  }
382 
383  PyErr_SetString(PyExc_KeyError, "Failed to parse variable in function Hitcore.get");
384  return NULL; //raise an exception
385 }
386 
387 ///////////////////////////
388 
389 ////// SET METHODS ////////
390 //specialist set_methods
391 void hc_set_x(Hitcore* self, double value) {self->x = value;}
392 void hc_set_y(Hitcore* self, double value) {self->y = value;}
393 void hc_set_z(Hitcore* self, double value) {self->z = value;}
394 void hc_set_t(Hitcore* self, double value) {self->t = value;}
395 void hc_set_px(Hitcore* self, double value) {self->px = value;}
396 void hc_set_py(Hitcore* self, double value) {self->py = value;}
397 void hc_set_pz(Hitcore* self, double value) {self->pz = value;}
398 void hc_set_energy(Hitcore* self, double value) {self->energy = value;}
399 void hc_set_mass(Hitcore* self, double value) {self->mass = value;}
400 void hc_set_local_weight (Hitcore* self, double weight) {self->weight = weight;}
401 void hc_set_bx(Hitcore* self, double value) {self->bx = value;}
402 void hc_set_by(Hitcore* self, double value) {self->by = value;}
403 void hc_set_bz(Hitcore* self, double value) {self->bz = value;}
404 void hc_set_ex(Hitcore* self, double value) {self->ex = value;}
405 void hc_set_ey(Hitcore* self, double value) {self->ey = value;}
406 void hc_set_ez(Hitcore* self, double value) {self->ez = value;}
407 void hc_set_sx(Hitcore* self, double value) {self->sx = value;}
408 void hc_set_sy(Hitcore* self, double value) {self->sy = value;}
409 void hc_set_sz(Hitcore* self, double value) {self->sz = value;}
410 void hc_set_pl(Hitcore* self, double value) {self->pl = value;}
411 void hc_set_tau(Hitcore* self, double value) {self->tau = value;}
412 void hc_set_e_dep(Hitcore* self, double value) {self->e_dep = value;}
413 void hc_set_charge(Hitcore* self, double value) {self->charge = value;}
414 
415 // Int
416 void hc_set_station (Hitcore* self, int value) {self->station = value;}
417 void hc_set_pid (Hitcore* self, int value) {self->pid = value;}
418 void hc_set_status (Hitcore* self, int value) {self->status = value;}
419 void hc_set_particle_number(Hitcore* self, int value) {self->particle = value;}
420 void hc_set_spill (Hitcore* self, int value) {self->spill = value;}
421 void hc_set_event_number (Hitcore* self, int value) {self->event = value;}
422 
423 void hc_set_global_weight(Hitcore* self, double global_weight) {
424  PyObject* key = weight_dict_key(self);
425  PyObject* value = Py_BuildValue("(d)", global_weight);
426  int success = PyDict_SetItem(global_weight_table, key, value);
427  Py_DECREF(value);
428  Py_DECREF(key);
429  if (success != 0) // error
430  return;
431 }
432 
433 static PyObject* hc_set_variables_to_python(PyObject* self, PyObject* args)
434 {
435  int int_i=0, dbl_i=0, j=0;
436  while(hc_set_dbl_function_list[dbl_i].variable != NULL) dbl_i++;
437  while(hc_set_int_function_list[int_i].variable != NULL) int_i++;
438  PyObject* list = PyList_New(dbl_i+int_i);
439  for(j=0; j<dbl_i; j++) PyList_SetItem(list, j, Py_BuildValue("s", hc_set_dbl_function_list[j]));
440  for(j=0; j<int_i; j++) PyList_SetItem(list, j+dbl_i, Py_BuildValue("s", hc_set_int_function_list[j]));
441  return list;
442 }
443 
444 //Set methods that use various types to index the variable in hitcore struct
446 {
447  int i;
448  for(i=0; i<n_set_dbl_variables; i++)
449  if ( strcmp(hc_set_dbl_function_list[i].variable, variable) == 0)
450  return hc_set_dbl_function_list[i].set_func;
451  return NULL;
452 }
453 
454 static void hc_set_dbl_by_string(Hitcore* self, const char* variable, double value, int* ierr)
455 {
457  if(func == NULL) {*ierr = -1; return;}
458  return func(self, value);
459 }
460 
462 {
463  int i;
464  for(i=0; i<n_set_int_variables; i++)
465  {
466  if ( strcmp(hc_set_int_function_list[i].variable, variable) == 0)
467  return hc_set_int_function_list[i].set_func;
468  }
469  return NULL;
470 }
471 
472 static void hc_set_int_by_string(Hitcore* self, const char* variable, double value, int* ierr)
473 {
475  if(func == NULL) {*ierr = -1; return;}
476  return func(self, value);
477 }
478 
479 
480 static PyObject* hc_set_python(PyObject* self, PyObject* args)
481 {
482  double value = 0.;
483  int error = 0;
484  const char* variable_name;
485 
486  //Try to turn arg into (string, double) and call get_string
487  error = PyArg_ParseTuple(args, "sd", &variable_name, &value);
488  if(error != 0)
489  {
490  hc_set_dbl_by_string((Hitcore*)self, variable_name, value, &error);
491  if(error >= 0) { Py_INCREF(Py_None); return Py_None;} //set a double
492  error = 0;
493  hc_set_int_by_string((Hitcore*)self, variable_name, value, &error);
494  if(error >= 0) { Py_INCREF(Py_None); return Py_None;} //set a int
495  }
496 
497 
498  PyErr_SetString(PyExc_KeyError, "Failed to parse variable in function Hitcore.set");
499  return NULL; //raise an exception
500 }
501 
502 /////////////////////////
503 
504 static PyMemberDef hc_Hitcore_members[] = {
505 {"x", T_DOUBLE, offsetof(Hitcore, x), 0, "x position"},
506 {"y", T_DOUBLE, offsetof(Hitcore, y), 0, "y position"},
507 {"z", T_DOUBLE, offsetof(Hitcore, z), 0, "z position"},
508 {"t", T_DOUBLE, offsetof(Hitcore, t), 0, "time"},
509 {"px", T_DOUBLE, offsetof(Hitcore, px), 0, "x momentum"},
510 {"py", T_DOUBLE, offsetof(Hitcore, py), 0, "y momentum"},
511 {"pz", T_DOUBLE, offsetof(Hitcore, pz), 0, "z momentum"},
512 {"energy", T_DOUBLE, offsetof(Hitcore, energy), 0, "energy"},
513 {"mass", T_DOUBLE, offsetof(Hitcore, mass), 0, "mass"},
514 {"local_weight", T_DOUBLE, offsetof(Hitcore, weight), 0, "local_weight"},
515 {"bx", T_DOUBLE, offsetof(Hitcore, bx), 0, "x magnetic field"},
516 {"by", T_DOUBLE, offsetof(Hitcore, by), 0, "y magnetic field"},
517 {"bz", T_DOUBLE, offsetof(Hitcore, bz), 0, "z magnetic field"},
518 {"ex", T_DOUBLE, offsetof(Hitcore, ex), 0, "x electric field"},
519 {"ey", T_DOUBLE, offsetof(Hitcore, ey), 0, "y electric field"},
520 {"ez", T_DOUBLE, offsetof(Hitcore, ez), 0, "z electric field"},
521 {"sx", T_DOUBLE, offsetof(Hitcore, sx), 0, "x spin"},
522 {"sy", T_DOUBLE, offsetof(Hitcore, sy), 0, "y spin"},
523 {"sz", T_DOUBLE, offsetof(Hitcore, sz), 0, "z spin"},
524 {"path_length", T_DOUBLE, offsetof(Hitcore, pl), 0, "path length"},
525 {"proper_time", T_DOUBLE, offsetof(Hitcore, tau), 0, "proper time"},
526 {"e_dep", T_DOUBLE, offsetof(Hitcore, e_dep), 0, "energy deposited"},
527 {"charge", T_DOUBLE, offsetof(Hitcore, charge), 0, "particle charge"},
528 {"pid", T_INT, offsetof(Hitcore, pid), 0, "PDG particle ID"},
529 {"spill", T_INT, offsetof(Hitcore, spill), 0, "spill number"},
530 {"event_number", T_INT, offsetof(Hitcore, event), 0, "event number"},
531 {"particle_number", T_INT, offsetof(Hitcore, particle), 0, "particle number (>0 if more than one particle in each event)"},
532 {"status", T_INT, offsetof(Hitcore, status), 0, "status - has particle stopped, died, decayed, etc"},
533 {"station", T_INT, offsetof(Hitcore, station), 0, "station or region"},
534 {NULL}
535 };
536 
537 static PyMethodDef hc_Hitcore_methods[] = {
538 {"get", (PyCFunction)hc_get_python, METH_VARARGS, "Get variable data"},
539 {"get_variables", (PyCFunction)hc_get_variables_to_python, METH_STATIC, "List of <var> strings appropriate for calls to get(<var>)"},
540 {"set", (PyCFunction)hc_set_python, METH_VARARGS, "Set variable data"},
541 {"set_variables", (PyCFunction)hc_set_variables_to_python, METH_STATIC, "List of <var> strings appropriate for calls to get(<var>)"},
542 {"clear_global_weights",(PyCFunction)hc_clear_global_weights, METH_STATIC, "Set all global weights to 1"},
543 {"get_weight_dict", (PyCFunction)hc_get_global_weight_dict, METH_STATIC, "Get the dictionary containing global weights - please don't edit unless you know what you are doing"},
544 {"integrity_test", (PyCFunction)hc_integrity_test, METH_STATIC, "Internal integrity check for Hitcore"},
545 {NULL}
546 };
547 
548 static PyObject* hc_integrity_test(PyObject* self, PyObject* args)
549 {
551  {
552  PyErr_SetString(PyExc_KeyError, "Internal error - Hitcore::get_function_list array failed integrity_test");
553  return NULL;
554  }
556  {
557  PyErr_SetString(PyExc_KeyError, "Internal error - Hitcore::get_function_list array failed integrity_test");
558  return NULL;
559  }
560 
562  {
563  PyErr_SetString(PyExc_KeyError, "Internal error - Hitcore::set_function_list array failed integrity_test");
564  return NULL;
565  }
567  {
568  PyErr_SetString(PyExc_KeyError, "Internal error - Hitcore::set_function_list array failed integrity_test");
569  return NULL;
570  }
571 
572  Py_INCREF(Py_None);
573  return Py_None;
574 }
575 
576 static PyTypeObject HitcoreType = {
577  PyObject_HEAD_INIT(NULL)
578  0, /*ob_size*/
579  "Hitcore.Hitcore", /*tp_name*/
580  sizeof(Hitcore), /*tp_basicsize*/
581  0, /*tp_itemsize*/
582  (destructor)hc_Hitcore_dealloc, /*tp_dealloc*/
583  0, /*tp_print*/
584  0, /*tp_getattr*/
585  0, /*tp_setattr*/
586  0, /*tp_compare*/
587  0, /*tp_repr*/
588  0, /*tp_as_number*/
589  0, /*tp_as_sequence*/
590  0, /*tp_as_mapping*/
591  0, /*tp_hash */
592  0, /*tp_call*/
593  0, /*tp_str*/
594  0, /*tp_getattro*/
595  0, /*tp_setattro*/
596  0, /*tp_as_buffer*/
597  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
598  "Hitcore objects", /* tp_doc */
599  0, /* tp_traverse */
600  0, /* tp_clear */
601  0, /* tp_richcompare */
602  0, /* tp_weaklistoffset */
603  0, /* tp_iter */
604  0, /* tp_iternext */
605  hc_Hitcore_methods, /* tp_methods */
606  hc_Hitcore_members, /* tp_members */
607  0, /* tp_getset */
608  0, /* tp_base */
609  0, /* tp_dict */
610  0, /* tp_descr_get */
611  0, /* tp_descr_set */
612  0, /* tp_dictoffset */
613  (initproc)hc_Hitcore_init, /* tp_init */
614  (allocfunc)hc_Hitcore_alloc, /* tp_alloc, called by new */
615  (newfunc)hc_Hitcore_new, /* tp_new */
616  (freefunc)hc_Hitcore_free, /* tp_free, called by dealloc */
617 };
618 
619 PyMODINIT_FUNC initHitcore(void)
620 {
621  HitcoreType.tp_new = PyType_GenericNew;
622  if (PyType_Ready(&HitcoreType) < 0) return;
623 
624  PyObject* m = Py_InitModule3("Hitcore", NULL, "Core module wrapped by Hit");
625  if (m == NULL) return;
626 
627 
628  Py_INCREF(&HitcoreType);
629  PyModule_AddObject(m, "Hitcore", (PyObject *)&HitcoreType);
630 
631  static void *hc_api[11] = {
633  (void*)hc_set_local_weight,
634  (void*)hc_set_global_weight,
635  (void*)vector_alloc,
636  (void*)vector_realloc,
637  (void*)vector_init,
638  (void*)vector_insert,
639  (void*)vector_el,
640  (void*)vector_el_bc,
641  (void*)vector_size,
642  (void*)vector_free
643  };
644 
645  PyObject* c_api_object = PyCObject_FromVoidPtr((void *)hc_api, NULL);
646  PyObject* hitcore_dict = PyModule_GetDict(m);
647  PyDict_SetItemString(hitcore_dict, "HITCORE_C_API", c_api_object);
648  while(hc_get_dbl_function_list[n_get_dbl_variables].variable != NULL)
650  while(hc_get_int_function_list[n_get_int_variables].variable != NULL)
652  while(hc_set_dbl_function_list[n_set_dbl_variables].variable != NULL)
654  while(hc_set_int_function_list[n_set_int_variables].variable != NULL)
656  if(global_weight_table == NULL) {
657  global_weight_table = PyDict_New();
658  if (global_weight_table == NULL) {
659  printf("Failed to allocate memory in initHitcore - trouble coming");
660  }
661  }
662 
663 
664 }
665 
666 
667 
668 
669 ////////////////////////// VECTOR /////////////////////
670 
671 static vector* vector_init (void* data, size_t data_length, size_t allocd_length, size_t object_size)
672 {
673  if(object_size == 0) return NULL;
674  vector* vec = malloc(sizeof(vector));
675  if(vec == NULL) return NULL;
676  vec->data = data;
677  vec->data_length = data_length;
678  vec->allocd_length = allocd_length;
679  vec->object_size = object_size;
680  return vec;
681 }
682 
683 static vector* vector_alloc(size_t object_size, int n_elements)
684 {
685  if(object_size == 0) return NULL; // probably okay, but better to be safe...
686  vector* vec = malloc(sizeof(vector));
687  if(vec == NULL) return NULL;
688  vec->data_length = object_size*n_elements;
689  vec->allocd_length = vec->data_length+1; //force allocd_length > 0
690  vec->object_size = object_size;
691  vec->data = malloc(vec->allocd_length);
692  if(vec->data == NULL) {free(vec); return NULL;}
693  return vec;
694 }
695 
696 static vector* vector_realloc (vector* vec, int n_elements)
697 {
698  if(vec == NULL) return NULL;
699  vec->data_length = vec->object_size*n_elements;
700  vec->allocd_length = vec->data_length+1;
701  vec->data = realloc(vec->data, vec->allocd_length);
702  if(vec->data == NULL) {free(vec); return NULL;} //out of memory
703  return vec;
704 }
705 
706 static void vector_free (vector* vec)
707 {
708  if(vec != NULL)
709  {
710  if(vec->data != NULL) free(vec->data);
711  free(vec);
712  }
713 }
714 
715 
716 static void vector_insert (vector* vec, void* start, void* end, size_t insert_point, int* ierr)
717 {
718  //first make sure we have space
719  size_t new_data_length = vec->data_length+(end-start);
720  size_t new_alloc = vec->allocd_length;
721  if (new_alloc == 0) new_alloc = 1;
722  while(new_alloc < new_data_length) new_alloc *= 2;
723  vec->data = realloc(vec->data, new_alloc);
724  if(vec->data == NULL) {*ierr = -1; vec->data_length = 0; vec->allocd_length = 0; return;} //out of memory
725 
726  //now move data forward in vec
727  int move_size = end-start;
728  if(insert_point+move_size > vec->data_length) move_size = vec->data_length-insert_point;
729  memmove(vec->data+insert_point+move_size, vec->data+insert_point, move_size);
730 
731  //now move data over
732  memmove(vec->data+insert_point, start, end-start); // I think false positive in valgrind
733  vec->data_length = new_data_length;
734  vec->allocd_length = new_alloc;
735 }
736 
737 static void* vector_el (vector* vec, int element)
738 {
739  return vec->data + vec->object_size*element;
740 }
741 
742 static void* vector_el_bc (vector* vec, int element)
743 {
744  if(element < 0 || vec->object_size*element >= vec->data_length)
745  return NULL;
746  return vec->data + vec->object_size*element;
747 }
748 
749 
750 //dummy function to remove warnings please don't call
751 void no_warn(void)
752 {
753  vector_free(NULL);
754 }
755 
756