MIDAS
Loading...
Searching...
No Matches
mana.cxx
Go to the documentation of this file.
1/********************************************************************\
2
3 Name: mana.c
4 Created by: Stefan Ritt
5
6 Contents: The system part of the MIDAS analyzer. Has to be
7 linked with analyze.c to form a complete analyzer
8
9 $Id$
10
11\********************************************************************/
12
13#include <assert.h>
14#include "midas.h"
15#include "msystem.h"
16#include "hardware.h"
17
18#include "mdsupport.h"
19
20#include "zlib.h"
21
22/*------------------------------------------------------------------*/
23
24/* cernlib includes */
25#ifdef OS_WINNT
26#define VISUAL_CPLUSPLUS
27#endif
28
29#ifdef OS_LINUX
30#define f2cFortran
31#endif
32
33#ifdef HAVE_HBOOK
34
35#include <cfortran.h>
36#include <hbook.h>
37
38/* missing in hbook.h */
39#ifndef HFNOV
40#define HFNOV(A1,A2) CCALLSFSUB2(HFNOV,hfnov,INT,FLOATV,A1,A2)
41#endif
42
43#ifndef HMERGE
44#define HMERGE(A1,A2,A3) CCALLSFSUB3(HMERGE,hmerge,INT,STRINGV,STRING,A1,A2,A3)
45#endif
46
47#endif /* HAVE_HBOOK */
48
50
51/*------------------------------------------------------------------*/
52
53#ifdef HAVE_ROOT
54
55#undef abs
56
57#include <assert.h>
58#include <TApplication.h>
59#include <TKey.h>
60#include <TROOT.h>
61#include <TH1.h>
62#include <TH2.h>
63#include <TFile.h>
64#include <TTree.h>
65#include <TLeaf.h>
66#include <TSocket.h>
67#include <TServerSocket.h>
68#include <TMessage.h>
69#include <TObjString.h>
70#include <TSystem.h>
71#include <TFolder.h>
72#include <TRint.h>
73#include <TCutG.h>
74
75#ifdef OS_LINUX
76#include <TThread.h>
77#endif
78
79/* Our own ROOT global objects */
80
82TFolder *gManaHistosFolder = NULL; // Container for all histograms
83TFile *gManaOutputFile = NULL; // MIDAS output file
85
86/* MIDAS output tree structure holing one tree per event type */
87
88typedef struct {
89 int event_id;
90 TTree *tree;
91 int n_branch;
92 char *branch_name;
93 int *branch_filled;
94 int *branch_len;
97
98typedef struct {
99 TFile *f;
100 int n_tree;
103
105
106//#warning HAVE_ROOT!
107//#else
108//#warning NO HAVE_ROOT!
109#endif /* HAVE_ROOT */
110
111/*------------------------------------------------------------------*/
112
113/* PVM include */
114
115#ifdef HAVE_PVM
116
118
120
121void pvm_debug(char *format, ...)
122{
124 char msg[256], str[256];
125
126 if (pvm_start_time == 0)
128
129 va_start(argptr, format);
130 vsprintf(msg, (char *) format, argptr);
131 va_end(argptr);
132 sprintf(str, "%1.3lf: %s", (ss_millitime() - pvm_start_time) / 1000.0, msg);
133 puts(str);
134#ifdef OS_LINUX
135 {
136 char cmd[256];
137
138 sprintf(cmd, "echo > /dev/console \"%s\"", str);
139 system(cmd);
140 }
141#endif
142}
143
144#undef STRICT
145#include <pvm3.h>
146#endif
147
148/*----- PVM TAGS and data ------------------------------------------*/
149
150/* buffer size must be larger than largest event (ODB dump!) */
151#define PVM_BUFFER_SIZE (1024*1024)
152
153#ifdef HAVE_PVM
154#define TAG_DATA 1
155#define TAG_BOR 2
156#define TAG_EOR 3
157#define TAG_EXIT 4
158#define TAG_INIT 5
159
160int pvm_n_task;
161int pvm_myparent;
163
164typedef struct {
165 int tid;
166 char host[80];
167 char *buffer;
168 int wp;
170 DWORD time;
172} PVM_CLIENT;
173
175
176int pvm_eor(int);
177int pvm_merge(void);
178void pvm_debug(char *format, ...);
180
181//#define PVM_DEBUG pvm_debug
182#define PVM_DEBUG
183
184#endif /* PVM */
185
187
188const char *bstr = " ";
189
190/*------------------------------------------------------------------*/
191
192/* items defined in analyzer.c */
193extern const char *analyzer_name;
195extern INT analyzer_init(void);
196extern INT analyzer_exit(void);
197extern INT analyzer_loop(void);
198extern INT ana_begin_of_run(INT run_number, char *error);
199extern INT ana_end_of_run(INT run_number, char *error);
200extern INT ana_pause_run(INT run_number, char *error);
201extern INT ana_resume_run(INT run_number, char *error);
202extern INT odb_size;
203
204/*---- globals -----------------------------------------------------*/
205
206/* ODB handle */
208
209/* run number */
211
212/* analyze_request defined in analyze.c or anasys.c */
214
215/* N-tupel booking and filling flag */
217
218/* list of locked histos (won't get cleared) */
220
221#ifdef extname
222int quest_[100];
223#else
224extern int QUEST[100];
225#endif
226
227extern INT pawc_size;
228
229/* default HBOOK record size */
230#define HBOOK_LREC 8190
231
232/* maximum extended event size */
233#ifndef EXT_EVENT_SIZE
234#define EXT_EVENT_SIZE (2*(MAX_EVENT_SIZE+sizeof(EVENT_HEADER)))
235#endif
236
238
239/* command line parameters */
240static struct {
244 char input_file_name[10][256];
249 char config_file_name[10][256];
250 char param[10][256];
251 char protect[10][256];
264
265static struct {
267 char description[1000];
268 void *data;
270 INT n;
272} clp_descrip[] = {
273
274 {
275 'c', "<filename1> Configuration file name(s). May contain a '%05d' to be\n\
276 <filename2> replaced by the run number. Up to ten files can be\n\
277 ... specified in one \"-c\" statement", clp.config_file_name, TID_STRING, 10}, {
278 'd', " Debug flag when started the analyzer fron a debugger.\n\
279 Prevents the system to kill the analyzer when the\n\
280 debugger stops at a breakpoint", &clp.debug, TID_BOOL, 0}, {
281 'D', " Start analyzer as a daemon in the background (UNIX only).",
282 &clp.daemon, TID_BOOL, 0}, {
283 'e', "<experiment> MIDAS experiment to connect to", clp.exp_name, TID_STRING, 1}, {
284 'f', " Filter mode. Write original events to output file\n\
285 only if analyzer accepts them (doesn't return ANA_SKIP).\n", &clp.filter, TID_BOOL, 0}, {
286 'h', "<hostname> MIDAS host to connect to when running the analyzer online",
287 clp.host_name, TID_STRING, 1}, {
288 'i', "<filename1> Input file name. May contain a '%05d' to be replaced by\n\
289 <filename2> the run number. Up to ten input files can be specified\n\
290 ... in one \"-i\" statement", clp.input_file_name, TID_STRING, 10}, {
291 'l', " If set, don't load histos from last histo file when\n\
292 running online.", &clp.no_load, TID_BOOL, 0}, {
293 'L', " HBOOK LREC size. Default is 8190.", &clp.lrec, TID_INT, 0}, {
294 'n', "<count> Analyze only \"count\" events.\n\
295 <first> <last>\n\
296 Analyze only events from \"first\" to \"last\".\n\
297 <first> <last> <n>\n\
298 Analyze every n-th event from \"first\" to \"last\".", clp.n, TID_INT, 4}, {
299 'o', "<filename> Output file name. Extension may be .mid (MIDAS binary),\n\
300 .asc (ASCII) or .rz (HBOOK). If the name contains a '%05d',\n\
301 one output file is generated for each run. Use \"OFLN\" as\n\
302 output file name to creaate a HBOOK shared memory instead\n\
303 of a file.", clp.output_file_name, TID_STRING, 1}, {
304 'p', "<param=value> Set individual parameters to a specific value.\n\
305 Overrides any setting in configuration files", clp.param, TID_STRING, 10}, {
306 'P', "<ODB tree> Protect an ODB subtree from being overwritten\n\
307 with the online data when ODB gets loaded from .mid file", clp.protect, TID_STRING, 10}, {
308 'q', " Quiet flag. If set, don't display run progress in\n\
309 offline mode.", &clp.quiet, TID_BOOL, 0}, {
310 'r', "<range> Range of run numbers to analyzer like \"-r 120 125\"\n\
311 to analyze runs 120 to 125 (inclusive). The \"-r\"\n\
312 flag must be used with a '%05d' in the input file name.", clp.run_number, TID_INT, 2},
313#ifdef HAVE_PVM
314 {
315 't', "<n> Parallelize analyzer using <n> tasks with PVM.", &clp.n_task,
316 TID_INT, 1}, {
317 'b', "<n> Buffer size for parallelization in kB.", &clp.pvm_buf_size,
318 TID_INT, 1},
319#endif
320#ifdef HAVE_ROOT
321 {
322 's', "<port> Start ROOT histo server under <port>. If port==0, don't start server.", &clp.root_port, TID_INT, 1}, {
323 'R', " Start ROOT interpreter after analysis has finished.",
324 &clp.start_rint, TID_BOOL, 0},
325#endif
326 {
327 'v', " Verbose output.", &clp.verbose, TID_BOOL, 0}, {
328 'w', " Produce row-wise N-tuples in outpur .rz file. By\n\
329 default, column-wise N-tuples are used.", &clp.rwnt, TID_BOOL, 0}, {
330 0}
332
337
338void update_stats();
339void odb_load(EVENT_HEADER * pevent);
340
341/*---- ODB records -------------------------------------------------*/
342
343#define ANALYZER_REQUEST_STR "\
344Event ID = INT : 0\n\
345Trigger mask = INT : -1\n\
346Sampling type = INT : 1\n\
347Buffer = STRING : [32] SYSTEM\n\
348Enabled = BOOL : 1\n\
349Client name = STRING : [32] \n\
350Host = STRING : [32] \n\
351"
352
353#define ANALYZER_STATS_STR "\
354Events received = DOUBLE : 0\n\
355Events per sec. = DOUBLE : 0\n\
356Events written = DOUBLE : 0\n\
357"
358
359/*-- interprete command line parameters ----------------------------*/
360
361INT getparam(int argc, char **argv)
362{
363 INT index, i, j, size;
364
365 /* parse command line parameters */
366 for (index = 1; index < argc;) {
367 /* search flag in parameter description */
368 if (argv[index][0] == '-') {
369 for (j = 0; clp_descrip[j].flag_char; j++)
370 if (argv[index][1] == clp_descrip[j].flag_char)
371 break;
372
373 if (!clp_descrip[j].flag_char)
374 goto usage;
375
376 if (clp_descrip[j].n > 0 && index >= argc - 1)
377 goto usage;
378 index++;
379
380 if (clp_descrip[j].type == TID_BOOL) {
381 *((BOOL *) clp_descrip[j].data) = TRUE;
382 continue;
383 }
384
385 do {
387 strcpy((char *) clp_descrip[j].data + clp_descrip[j].index * 256,
388 argv[index]);
389 else
392
393 if (clp_descrip[j].n > 1)
394 clp_descrip[j].index++;
395
396 if (clp_descrip[j].index > clp_descrip[j].n) {
397 printf("Note more than %d options possible for flag -%c\n",
399 return 0;
400 }
401
402 index++;
403
404 } while (index < argc && argv[index][0] != '-');
405
406 } else
407 goto usage;
408 }
409
410 return SUCCESS;
411
412 usage:
413
414 printf("usage: analyzer [options]\n\n");
415 printf("valid options are:\n");
416 for (i = 0; clp_descrip[i].flag_char; i++)
418
419 return 0;
420}
421
422/*-- add </logger/data dir> before filename ------------------------*/
423
424void add_data_dir(char *result, char *file)
425{
426 HNDLE hDB, hkey;
427 char str[256];
428 int size;
429
431 db_find_key(hDB, 0, "/Logger/Data dir", &hkey);
432
433 if (hkey) {
434 size = sizeof(str);
435 db_get_data(hDB, hkey, str, &size, TID_STRING);
436 if (str[strlen(str) - 1] != DIR_SEPARATOR)
438 strcat(str, file);
439 strcpy(result, str);
440 } else
441 strcpy(result, file);
442}
443
444/*-- db_get_event_definition ---------------------------------------*/
445
453
455{
456 INT i, index, status, size, type;
457 char str[80];
459 WORD id;
460 static EVENT_DEF *event_def = NULL;
461 static int n_cache = 0;
462
463 /* search free cache entry */
464 for (index = 0; index < n_cache; index++)
466 return &event_def[index];
467
468 /* If we get here, we have an undefined ID;
469 allocate memory for it, zero it, then cache the ODB data */
470 n_cache = index + 1;
471
473 assert(event_def);
474
475 memset(&event_def[index], 0, sizeof(EVENT_DEF));
476
477 /* check for system events */
478 if (event_id < 0) {
479 event_def[index].event_id = event_id;
480 event_def[index].format = FORMAT_ASCII;
481 event_def[index].hDefKey = 0;
482 event_def[index].disabled = FALSE;
483 return &event_def[index];
484 }
485
486 status = db_find_key(hDB, 0, "/equipment", &hKeyRoot);
487 if (status != DB_SUCCESS) {
488 cm_msg(MERROR, "db_get_event_definition", "cannot find /equipment entry in ODB");
489 return NULL;
490 }
491
492 for (i = 0;; i++) {
493 /* search for equipment with specific name */
495 if (status == DB_NO_MORE_SUBKEYS) {
496 cm_msg(MERROR, "db_get_event_definition", "Cannot find event id %d under /equipment", event_id);
497 return NULL;
498 }
499
500 size = sizeof(id);
501 status = db_get_value(hDB, hKey, "Common/Event ID", &id, &size, TID_WORD, TRUE);
502 if (status != DB_SUCCESS)
503 continue;
504
505 size = sizeof(type);
506 status = db_get_value(hDB, hKey, "Common/Type", &type, &size, TID_INT, TRUE);
507 if (status != DB_SUCCESS)
508 continue;
509
510 if (id == event_id) {
511 /* set cache entry */
512 event_def[index].event_id = id;
513 event_def[index].type = type;
514
515 size = sizeof(str);
516 str[0] = 0;
517 db_get_value(hDB, hKey, "Common/Format", str, &size, TID_STRING, TRUE);
518
519 if (equal_ustring(str, "Fixed"))
520 event_def[index].format = FORMAT_FIXED;
521 else if (equal_ustring(str, "ASCII"))
522 event_def[index].format = FORMAT_ASCII;
523 else if (equal_ustring(str, "MIDAS"))
524 event_def[index].format = FORMAT_MIDAS;
525 else if (equal_ustring(str, "YBOS"))
526 event_def[index].format = FORMAT_YBOS;
527 else if (equal_ustring(str, "DUMP"))
528 event_def[index].format = FORMAT_DUMP;
529 else {
530 cm_msg(MERROR, "db_get_event_definition", "unknown data format");
531 event_def[index].event_id = 0;
532 return NULL;
533 }
534
535 db_find_key(hDB, hKey, "Variables", &event_def[index].hDefKey);
536 return &event_def[index];
537 }
538 }
539}
540
541/*-- functions for internal tests ----------------------------------*/
542
544int n_test = 0;
545
547{
548 int i;
549
550 /* check if test already registered */
551 for (i = 0; i < n_test; i++)
552 if (tl[i] == t)
553 break;
554 if (i < n_test) {
555 t->registered = TRUE;
556 return;
557 }
558
559 /* allocate space for pointer to test */
560 if (n_test == 0) {
561 tl = (ANA_TEST **) malloc(2 * sizeof(void *));
562
563 /* define "always true" test */
564 tl[0] = (ANA_TEST *) malloc(sizeof(ANA_TEST));
565 strcpy(tl[0]->name, "Always true");
566 tl[0]->count = 0;
567 tl[0]->previous_count = 0;
568 tl[0]->value = TRUE;
569 tl[0]->registered = TRUE;
570 n_test++;
571 } else
572 tl = (ANA_TEST **) realloc(tl, (n_test + 1) * sizeof(void *));
573
574 tl[n_test] = t;
575 t->count = 0;
576 t->value = FALSE;
577 t->registered = TRUE;
578
579 n_test++;
580}
581
583{
584 int i;
585
586 /* clear all tests in interal list */
587 for (i = 0; i < n_test; i++) {
588 tl[i]->count = 0;
589 tl[i]->value = FALSE;
590 }
591
592 /* set "always true" test */
593 if (n_test > 0)
594 tl[0]->value = TRUE;
595}
596
598{
599 int i;
600
601 /* increment test counters based on their value and reset them */
602 for (i = 0; i < n_test; i++) {
603 if (tl[i]->value)
604 tl[i]->count++;
605 if (i > 0)
606 tl[i]->value = FALSE;
607 }
608}
609
611{
612 int i;
613 char str[256];
614 float rate;
615
616 /* write all test counts to /analyzer/tests/<name> */
617 for (i = 0; i < n_test; i++) {
618 sprintf(str, "/%s/Tests/%s/Count", analyzer_name, tl[i]->name);
619 db_set_value(hDB, 0, str, &tl[i]->count, sizeof(DWORD), 1, TID_DWORD);
620
621 /* calcluate rate */
622 if (delta_time > 0) {
623 rate = (float) ((tl[i]->count - tl[i]->previous_count) / (delta_time / 1000.0));
624 tl[i]->previous_count = tl[i]->count;
625 sprintf(str, "/%s/Tests/%s/Rate [Hz]", analyzer_name, tl[i]->name);
626 db_set_value(hDB, 0, str, &rate, sizeof(float), 1, TID_FLOAT);
627 }
628 }
629}
630
631/*-- load parameters specified on command line ---------------------*/
632
634{
635 INT i, size, index, status;
636 HNDLE hkey;
637 char file_name[256];
638 char value_string[80];
639 char param_string[80];
640 char data[32];
641
642 /* loop over configutation file names */
643 for (i = 0; clp.config_file_name[i][0] && i < 10; i++) {
644 if (strchr(clp.config_file_name[i], '%') != NULL)
645 sprintf(file_name, clp.config_file_name[i], run_number);
646 else
647 strcpy(file_name, clp.config_file_name[i]);
648
649 /* load file under "/" */
650 if (db_load(hDB, 0, file_name, FALSE) == DB_SUCCESS)
651 printf("Configuration file \"%s\" loaded\n", file_name);
652 }
653
654 /* loop over parameters */
655 for (i = 0; clp.param[i][0] && i < 10; i++) {
656 if (strchr(clp.param[i], '=') == NULL) {
657 printf("Error: parameter %s contains no value\n", clp.param[i]);
658 } else {
659 strcpy(value_string, strchr(clp.param[i], '=') + 1);
660 strcpy(param_string, clp.param[i]);
661 *strchr(param_string, '=') = 0;
662
663 index = 0;
664 if (strchr(param_string, '[') != NULL) {
665 index = atoi(strchr(param_string, '[') + 1);
666 *strchr(param_string, '[') = 0;
667 }
668
669 char str[MAX_ODB_PATH];
670
671 if (param_string[0] == '/')
672 strcpy(str, param_string);
673 else
674 sprintf(str, "/%s/Parameters/%s", analyzer_name, param_string);
675 db_find_key(hDB, 0, str, &hkey);
676 if (hkey == 0) {
677 printf("Error: cannot find parameter %s in ODB\n", str);
678 } else {
679 KEY key;
681 db_sscanf(value_string, data, &size, 0, key.type);
682
684 if (status == DB_SUCCESS)
685 printf("Parameter %s changed to %s\n", str, value_string);
686 else
687 printf("Cannot change parameter %s\n", str);
688 }
689 }
690 }
691
692 /* let parameter changes propagate to modules */
693 cm_yield(0);
694
695 return SUCCESS;
696}
697
698/*-- book N-tuples from ODB bank structures ------------------------*/
699
700char hbook_types[][8] = {
701 "",
702 ":U:8", /* TID_BYTE */
703 ":I:8", /* TID_SBYTE */
704 ":I:8", /* TID_CHAR */
705 ":U:16", /* TID_WORD */
706 ":I:16", /* TID_SHORT */
707 ":U*4", /* TID_DWORD */
708 ":I*4", /* TID_INT */
709 ":I*4", /* TID_BOOL */
710 ":R*4", /* TID_FLOAT */
711 ":R*8", /* TID_DOUBLE */
712 ":U*4", /* TID_BITFIELD */
713 ":C:32", /* TID_STRING */
714 "", /* TID_ARRAY */
715 "", /* TID_STRUCT */
716 "", /* TID_KEY */
717 "", /* TID_LINK */
718 "", /* TID_LAST */
719
720};
721
724
726{
727 char str[80];
728 HNDLE hkey;
729
730 /* close previously opened hot link */
731 sprintf(str, "/%s/Bank switches", analyzer_name);
732 db_find_key(hDB, 0, str, &hkey);
734
735#ifdef HAVE_HBOOK
736 book_ntuples();
737 printf("N-tuples rebooked\n");
738#endif
739#ifdef HAVE_ROOT
740 book_ttree();
741 printf("ROOT TTree rebooked\n");
742#endif
743}
744
745#ifdef HAVE_HBOOK
746INT book_ntuples(void)
747{
748 INT index, i, j, status, n_tag, size, id;
749 HNDLE hkey;
750 KEY key;
751 int *t;
752 char ch_tags[2000];
753 char rw_tag[512][8];
754 char str[80], str2[80], key_name[NAME_LENGTH], block_name[NAME_LENGTH];
755 BANK_LIST *bank_list;
757
758 /* check global N-tuple flag */
759 ntuple_flag = 1;
760 size = sizeof(ntuple_flag);
761 sprintf(str, "/%s/Book N-tuples", analyzer_name);
763
764 if (!ntuple_flag)
765 return SUCCESS;
766
767 /* copy output flag from ODB to bank_list */
768 for (i = 0; analyze_request[i].event_name[0]; i++) {
769 bank_list = analyze_request[i].bank_list;
770
771 if (bank_list != NULL)
772 for (; bank_list->name[0]; bank_list++) {
773 sprintf(str, "/%s/Bank switches/%s", analyzer_name, bank_list->name);
774 bank_list->output_flag = FALSE;
775 size = sizeof(DWORD);
776 db_get_value(hDB, 0, str, &bank_list->output_flag, &size, TID_DWORD, TRUE);
777 }
778 }
779
780 /* hot link bank switches to N-tuple re-booking */
781 sprintf(str, "/%s/Bank switches", analyzer_name);
782 status = db_find_key(hDB, 0, str, &hkey);
783 if (status != DB_SUCCESS) {
784 cm_msg(MERROR, "book_ntuples", "Cannot find key \'%s\', status %d", str, status);
785 return SUCCESS;
786 }
787
789
790 if (!clp.rwnt) {
791 /* book CW N-tuples */
792
793 /* go through all analyzer requests (events) */
794 for (index = 0; analyze_request[index].event_name[0]; index++) {
795 /* book N-tuple with evend ID */
797 bstr);
798
799 /* book run number/event number/time */
800 strcpy(str, "Number");
801 strcpy(str2, "Run:U*4,Number:U*4,Time:U*4");
802 t = (int *) (&analyze_request[index].number.run);
803 HBNAME(analyze_request[index].ar_info.event_id, str, t, str2);
804
805 bank_list = analyze_request[index].bank_list;
806 if (bank_list == NULL) {
807 /* book fixed event */
808 event_def =
809 db_get_event_definition((short int) analyze_request[index].ar_info.
810 event_id);
811 if (event_def == NULL) {
812 cm_msg(MERROR, "book_ntuples", "Cannot find definition of event %s in ODB",
813 analyze_request[index].event_name);
814 return 0;
815 }
816
817 ch_tags[0] = 0;
818 for (i = 0;; i++) {
819 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
821 break;
822
824
825 /* convert blanks etc to '_' */
826 strcpy(str, key.name);
827 for (j = 0; str[j]; j++) {
828 if (!(str[j] >= 'a' && str[j] <= 'z') &&
829 !(str[j] >= 'A' && str[j] <= 'Z') && !(str[j] >= '0'
830 && str[j] <= '9'))
831 str[j] = '_';
832 }
834 str[0] = 0;
835
836 if (key.num_values > 1)
837 sprintf(str, "(%d)", key.num_values);
838
839 if (hbook_types[key.type] != NULL)
841 else {
842 cm_msg(MERROR, "book_ntuples",
843 "Key %s in event %s is of type %s with no HBOOK correspondence",
846 return 0;
847 }
849 strcat(ch_tags, ",");
850 }
851
852 ch_tags[strlen(ch_tags) - 1] = 0;
853 db_get_record_size(hDB, event_def->hDefKey, 0, &size);
854 analyze_request[index].addr = calloc(1, size);
855
856 strcpy(block_name, analyze_request[index].event_name);
857 block_name[8] = 0;
858
859 HBNAME(analyze_request[index].ar_info.event_id, block_name,
861 } else {
862 /* go thorough all banks in bank_list */
863 for (; bank_list->name[0]; bank_list++) {
864 if (bank_list->output_flag == 0)
865 continue;
866
867 if (bank_list->type != TID_STRUCT) {
868 sprintf(str, "N%s[0,%d]", bank_list->name, bank_list->size);
869 INT *t = (INT *) & bank_list->n_data;
870 HBNAME(analyze_request[index].ar_info.event_id,
871 bank_list->name, t, str);
872
873 sprintf(str, "%s(N%s)", bank_list->name, bank_list->name);
874
875 /* define variable length array */
876 if (hbook_types[bank_list->type] != NULL)
877 strcat(str, hbook_types[bank_list->type]);
878 else {
879 cm_msg(MERROR, "book_ntuples",
880 "Bank %s is of type %s with no HBOOK correspondence",
881 bank_list->name, rpc_tid_name(bank_list->type));
882 return 0;
883 }
884
885 if (rpc_tid_size(bank_list->type) == 0) {
886 cm_msg(MERROR, "book_ntuples",
887 "Bank %s is of type with unknown size", bank_list->name);
888 return 0;
889 }
890
891 bank_list->addr =
892 calloc(bank_list->size, MAX(4, rpc_tid_size(bank_list->type)));
893
894 HBNAME(analyze_request[index].ar_info.event_id, bank_list->name,
895 bank_list->addr, str);
896 } else {
897 /* define structured bank */
898 ch_tags[0] = 0;
899 for (i = 0;; i++) {
900 status = db_enum_key(hDB, bank_list->def_key, i, &hkey);
902 break;
903
905
906 /* convert blanks etc to '_' */
907 strcpy(str, key.name);
908 for (j = 0; str[j]; j++) {
909 if (!(str[j] >= 'a' && str[j] <= 'z') &&
910 !(str[j] >= 'A' && str[j] <= 'Z') && !(str[j] >= '0'
911 && str[j] <= '9'))
912 str[j] = '_';
913 }
915 str[0] = 0;
916
917 if (key.num_values > 1)
918 sprintf(str, "(%d)", key.num_values);
919
920 if (hbook_types[key.type] != NULL)
922 else {
923 cm_msg(MERROR, "book_ntuples",
924 "Key %s in bank %s is of type %s with no HBOOK correspondence",
925 key.name, bank_list->name, rpc_tid_name(key.type));
926 return 0;
927 }
929 strcat(ch_tags, ",");
930 }
931
932 ch_tags[strlen(ch_tags) - 1] = 0;
933 bank_list->addr = calloc(1, bank_list->size);
934
935 HBNAME(analyze_request[index].ar_info.event_id, bank_list->name,
936 bank_list->addr, ch_tags);
937 }
938 }
939 }
940
941 /* HPRNT(analyze_request[index].ar_info.event_id); */
942 }
943 } else {
944 /* book RW N-tuples */
945
946 /* go through all analyzer requests (events) */
947 for (index = 0; analyze_request[index].event_name[0]; index++) {
948 /* get pointer to event definition */
949 event_def =
950 db_get_event_definition((short int) analyze_request[index].ar_info.event_id);
951
952 /* skip if not found */
953 if (!event_def)
954 continue;
955
956 /* don't book NT if not requested */
957 if (analyze_request[index].rwnt_buffer_size == 0) {
958 event_def->disabled = TRUE;
959 continue;
960 }
961
962 n_tag = 0;
963
964 strcpy(rw_tag[n_tag++], "Run");
965 strcpy(rw_tag[n_tag++], "Number");
966 strcpy(rw_tag[n_tag++], "Time");
967
968 if (clp.verbose) {
969 printf("NT #%d-1: Run\n", analyze_request[index].ar_info.event_id);
970 printf("NT #%d-2: Number\n", analyze_request[index].ar_info.event_id);
971 printf("NT #%d-3: Time\n", analyze_request[index].ar_info.event_id);
972 }
973
974 bank_list = analyze_request[index].bank_list;
975 if (bank_list == NULL) {
976 /* book fixed event */
977
978 for (i = 0;; i++) {
979 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
981 break;
982
984
985 /* convert blanks etc to '_' */
986 strcpy(key_name, key.name);
987 for (j = 0; key_name[j]; j++) {
988 if (!(key_name[j] >= 'a' && key_name[j] <= 'z') &&
989 !(key_name[j] >= 'A' && key_name[j] <= 'Z') &&
990 !(key_name[j] >= '0' && key_name[j] <= '9'))
991 key_name[j] = '_';
992 }
993
994 if (key.num_values > 1)
995 for (j = 0; j < key.num_values; j++) {
996 sprintf(str, "%s%d", key_name, j);
997 strncpy(rw_tag[n_tag++], str, 8);
998
999 if (clp.verbose)
1000 printf("NT #%d-%d: %s\n", analyze_request[index].ar_info.event_id,
1001 n_tag + 1, str);
1002
1003 if (n_tag >= 512) {
1004 cm_msg(MERROR, "book_ntuples",
1005 "Too much tags for RW N-tupeles (512 maximum)");
1006 return 0;
1007 }
1008 } else {
1009 strncpy(rw_tag[n_tag++], key_name, 8);
1010
1011 if (clp.verbose)
1012 printf("NT #%d-%d: %s\n", analyze_request[index].ar_info.event_id,
1013 n_tag, key_name);
1014 }
1015
1016 if (n_tag >= 512) {
1017 cm_msg(MERROR, "book_ntuples",
1018 "Too much tags for RW N-tupeles (512 maximum)");
1019 return 0;
1020 }
1021 }
1022 } else {
1023 /* go through all banks in bank_list */
1024 for (; bank_list->name[0]; bank_list++) {
1025 /* remember tag offset in n_data variable */
1026 bank_list->n_data = n_tag;
1027
1028 if (bank_list->output_flag == 0)
1029 continue;
1030
1031 if (bank_list->type != TID_STRUCT) {
1032 for (i = 0; i < (INT) bank_list->size; i++) {
1033 sprintf(str, "%s%d", bank_list->name, i);
1034 strncpy(rw_tag[n_tag++], str, 8);
1035
1036 if (clp.verbose)
1037 printf("NT #%d-%d: %s\n", analyze_request[index].ar_info.event_id,
1038 n_tag, str);
1039 if (n_tag >= 512) {
1040 cm_msg(MERROR, "book_ntuples",
1041 "Too much tags for RW N-tupeles (512 maximum)");
1042 return 0;
1043 }
1044 }
1045 } else {
1046 /* define structured bank */
1047 for (i = 0;; i++) {
1048 status = db_enum_key(hDB, bank_list->def_key, i, &hkey);
1050 break;
1051
1052 db_get_key(hDB, hkey, &key);
1053
1054 /* convert blanks etc to '_' */
1055 strcpy(key_name, key.name);
1056 for (j = 0; key_name[j]; j++) {
1057 if (!(key_name[j] >= 'a' && key_name[j] <= 'z') &&
1058 !(key_name[j] >= 'A' && key_name[j] <= 'Z') &&
1059 !(key_name[j] >= '0' && key_name[j] <= '9'))
1060 key_name[j] = '_';
1061 }
1062
1063 if (key.num_values > 1)
1064 for (j = 0; j < key.num_values; j++) {
1065 sprintf(str, "%s%d", key_name, j);
1066 strncpy(rw_tag[n_tag++], str, 8);
1067
1068 if (clp.verbose)
1069 printf("NT #%d-%d: %s\n",
1070 analyze_request[index].ar_info.event_id, n_tag, str);
1071
1072 if (n_tag >= 512) {
1073 cm_msg(MERROR, "book_ntuples",
1074 "Too much tags for RW N-tupeles (512 maximum)");
1075 return 0;
1076 }
1077 } else {
1078 strncpy(rw_tag[n_tag++], key_name, 8);
1079 if (clp.verbose)
1080 printf("NT #%d-%d: %s\n",
1081 analyze_request[index].ar_info.event_id, n_tag,
1082 key_name);
1083 }
1084
1085 if (n_tag >= 512) {
1086 cm_msg(MERROR, "book_ntuples",
1087 "Too much tags for RW N-tupeles (512 maximum)");
1088 return 0;
1089 }
1090 }
1091 }
1092 }
1093 }
1094
1095 /* book N-tuple with evend ID */
1096 strcpy(block_name, analyze_request[index].event_name);
1097 block_name[8] = 0;
1098
1100 if (HEXIST(id))
1101 HDELET(id);
1102
1103 if (clp.online || equal_ustring(clp.output_file_name, "OFLN"))
1104 HBOOKN(id, block_name, n_tag, bstr,
1105 n_tag * analyze_request[index].rwnt_buffer_size, rw_tag);
1106 else {
1107 strcpy(str, "//OFFLINE");
1108 HBOOKN(id, block_name, n_tag, str, 5120, rw_tag);
1109 }
1110
1111 if (!HEXIST(id)) {
1112 printf("\n");
1113 cm_msg(MINFO, "book_ntuples",
1114 "Cannot book N-tuple #%d. Increase PAWC size via the -s flag or switch off banks",
1115 id);
1116 }
1117 }
1118 }
1119
1120 return SUCCESS;
1121}
1122#endif /* HAVE_HBOOK */
1123
1124/*-- book TTree from ODB bank structures ---------------------------*/
1125
1126#ifdef HAVE_ROOT
1127
1128char ttree_types[][8] = {
1129 "",
1130 "b", /* TID_BYTE */
1131 "B", /* TID_SBYTE */
1132 "b", /* TID_CHAR */
1133 "s", /* TID_WORD */
1134 "S", /* TID_SHORT */
1135 "i", /* TID_DWORD */
1136 "I", /* TID_INT */
1137 "I", /* TID_BOOL */
1138 "F", /* TID_FLOAT */
1139 "D", /* TID_DOUBLE */
1140 "i", /* TID_BITFIELD */
1141 "C", /* TID_STRING */
1142 "", /* TID_ARRAY */
1143 "", /* TID_STRUCT */
1144 "", /* TID_KEY */
1145 "", /* TID_LINK */
1146 "", /* TID_LAST */
1147
1148};
1149
1151{
1152 INT index, i, status, size;
1153 HNDLE hkey;
1154 KEY key;
1155 char leaf_tags[2000];
1156 char str[80];
1157 BANK_LIST *bank_list;
1159 EVENT_TREE *et;
1160
1161 /* check global N-tuple flag */
1162 ntuple_flag = 1;
1163 size = sizeof(ntuple_flag);
1164 sprintf(str, "/%s/Book TTree", analyzer_name);
1165 db_get_value(hDB, 0, str, &ntuple_flag, &size, TID_BOOL, TRUE);
1166
1167 if (!ntuple_flag)
1168 return SUCCESS;
1169
1170 /* copy output flag from ODB to bank_list */
1171 for (i = 0; analyze_request[i].event_name[0]; i++) {
1172 bank_list = analyze_request[i].bank_list;
1173
1174 if (bank_list != NULL)
1175 for (; bank_list->name[0]; bank_list++) {
1176 sprintf(str, "/%s/Bank switches/%s", analyzer_name, bank_list->name);
1177 bank_list->output_flag = FALSE;
1178 size = sizeof(DWORD);
1179 db_get_value(hDB, 0, str, &bank_list->output_flag, &size, TID_DWORD, TRUE);
1180 }
1181 }
1182
1183 /* hot link bank switches to N-tuple re-booking */
1184 sprintf(str, "/%s/Bank switches", analyzer_name);
1185 status = db_find_key(hDB, 0, str, &hkey);
1186 if (status != DB_SUCCESS) {
1187 cm_msg(MERROR, "book_ttree", "Cannot find key \'%s\', status %d", str, status);
1188 return SUCCESS;
1189 }
1190
1192
1193 /* go through all analyzer requests (events) */
1194 for (index = 0; analyze_request[index].event_name[0]; index++) {
1195 /* create tree */
1196 tree_struct.n_tree++;
1197 if (tree_struct.n_tree == 1)
1198 tree_struct.event_tree = (EVENT_TREE *) malloc(sizeof(EVENT_TREE));
1199 else
1200 tree_struct.event_tree =
1201 (EVENT_TREE *) realloc(tree_struct.event_tree,
1202 sizeof(EVENT_TREE) * tree_struct.n_tree);
1203
1204 et = tree_struct.event_tree + (tree_struct.n_tree - 1);
1205
1207 et->n_branch = 0;
1208
1209 /* create tree */
1210 sprintf(str, "Event \"%s\", ID %d", analyze_request[index].event_name,
1211 et->event_id);
1212 et->tree = new TTree((const char *)analyze_request[index].event_name, (const char *)str);
1213#if (ROOT_VERSION_CODE >= 262401)
1214 et->tree->SetCircular(analyze_request[index].rwnt_buffer_size);
1215#endif
1216
1217 /* book run number/event number/time */
1218 et->branch = (TBranch **) malloc(sizeof(TBranch *));
1219 et->branch_name = (char *) malloc(NAME_LENGTH);
1220 et->branch_filled = (int *) malloc(sizeof(int));
1221 et->branch_len = (int *) malloc(sizeof(int));
1222
1223 et->branch[et->n_branch] =
1224 et->tree->Branch("Number", &analyze_request[index].number,
1225 "Run/I:Number/I:Time/i");
1226 strcpy(et->branch_name, "Number");
1227 et->n_branch++;
1228
1229 bank_list = analyze_request[index].bank_list;
1230 if (bank_list == NULL) {
1231 /* book fixed event */
1232 event_def =
1233 db_get_event_definition((short int) analyze_request[index].ar_info.event_id);
1234 if (event_def == NULL) {
1235 cm_msg(MERROR, "book_ttree", "Cannot find definition of event %s in ODB",
1236 analyze_request[index].event_name);
1237 return 0;
1238 }
1239
1240 leaf_tags[0] = 0;
1241 for (i = 0;; i++) {
1242 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
1244 break;
1245
1246 db_get_key(hDB, hkey, &key);
1247
1249
1250 if (key.num_values > 1)
1252
1253 strcat(leaf_tags, "/");
1254
1255 if (ttree_types[key.type] != NULL)
1257 else {
1258 cm_msg(MERROR, "book_ttree",
1259 "Key %s in event %s is of type %s with no TTREE correspondence",
1262 return 0;
1263 }
1264 strcat(leaf_tags, ":");
1265 }
1266
1267 leaf_tags[strlen(leaf_tags) - 1] = 0; /* delete last ':' */
1268
1269 et->branch =
1270 (TBranch **) realloc(et->branch, sizeof(TBranch *) * (et->n_branch + 1));
1271 et->branch_name =
1272 (char *) realloc(et->branch_name, NAME_LENGTH * (et->n_branch + 1));
1273 et->branch_filled =
1274 (int *) realloc(et->branch_filled, sizeof(int) * (et->n_branch + 1));
1275 et->branch_len =
1276 (int *) realloc(et->branch_len, sizeof(int) * (et->n_branch + 1));
1277
1278 et->branch[et->n_branch] =
1279 et->tree->Branch((const char*)analyze_request[index].event_name, (const char*)NULL, leaf_tags);
1280 strcpy(&et->branch_name[et->n_branch * NAME_LENGTH],
1282 et->n_branch++;
1283 } else {
1284 /* go thorough all banks in bank_list */
1285 for (; bank_list->name[0]; bank_list++) {
1286 if (bank_list->output_flag == 0)
1287 continue;
1288
1289 if (bank_list->type != TID_STRUCT) {
1290 sprintf(leaf_tags, "n%s/I:%s[n%s]/", bank_list->name, bank_list->name,
1291 bank_list->name);
1292
1293 /* define variable length array */
1294 if (ttree_types[bank_list->type] != NULL)
1295 strcat(leaf_tags, ttree_types[bank_list->type]);
1296 else {
1297 cm_msg(MERROR, "book_ttree",
1298 "Bank %s is of type %s with no TTREE correspondence",
1299 bank_list->name, rpc_tid_name(bank_list->type));
1300 return 0;
1301 }
1302
1303 if (rpc_tid_size(bank_list->type) == 0) {
1304 cm_msg(MERROR, "book_ttree", "Bank %s is of type with unknown size",
1305 bank_list->name);
1306 return 0;
1307 }
1308
1309 et->branch =
1310 (TBranch **) realloc(et->branch,
1311 sizeof(TBranch *) * (et->n_branch + 1));
1312 et->branch_name =
1313 (char *) realloc(et->branch_name, NAME_LENGTH * (et->n_branch + 1));
1314 et->branch_filled =
1315 (int *) realloc(et->branch_filled, sizeof(int) * (et->n_branch + 1));
1316 et->branch_len =
1317 (int *) realloc(et->branch_len, sizeof(int) * (et->n_branch + 1));
1318
1319 et->branch[et->n_branch] =
1320 et->tree->Branch((const char*)bank_list->name, (const char*)NULL, leaf_tags);
1321 strcpy(&et->branch_name[et->n_branch * NAME_LENGTH], bank_list->name);
1322 et->n_branch++;
1323 } else {
1324 /* define structured bank */
1325 leaf_tags[0] = 0;
1326 for (i = 0;; i++) {
1327 status = db_enum_key(hDB, bank_list->def_key, i, &hkey);
1329 break;
1330
1331 db_get_key(hDB, hkey, &key);
1332
1334
1335 if (key.num_values > 1)
1337
1338 strcat(leaf_tags, "/");
1339
1340 if (ttree_types[key.type] != NULL)
1342 else {
1343 cm_msg(MERROR, "book_ttree",
1344 "Key %s in bank %s is of type %s with no HBOOK correspondence",
1345 key.name, bank_list->name, rpc_tid_name(key.type));
1346 return 0;
1347 }
1348 strcat(leaf_tags, ":");
1349 }
1350
1351 leaf_tags[strlen(leaf_tags) - 1] = 0;
1352
1353 et->branch =
1354 (TBranch **) realloc(et->branch,
1355 sizeof(TBranch *) * (et->n_branch + 1));
1356 et->branch_name =
1357 (char *) realloc(et->branch_name, NAME_LENGTH * (et->n_branch + 1));
1358 et->branch_filled =
1359 (int *) realloc(et->branch_filled, sizeof(int) * (et->n_branch + 1));
1360 et->branch_len =
1361 (int *) realloc(et->branch_len, sizeof(int) * (et->n_branch + 1));
1362
1363 et->branch[et->n_branch] =
1364 et->tree->Branch((const char*)bank_list->name, (const char*)NULL, leaf_tags);
1365 strcpy(&et->branch_name[et->n_branch * NAME_LENGTH], bank_list->name);
1366 et->n_branch++;
1367 }
1368 }
1369 }
1370 }
1371
1372 return SUCCESS;
1373}
1374
1375/*-- root histogram routines ---------------------------------------*/
1376
1377// Save all objects from given directory into given file
1378INT SaveRootHistograms(TFolder * folder, const char *filename)
1379{
1381 TFile *outf = new TFile(filename, "RECREATE", "Midas Analyzer Histograms");
1382 if (outf == 0) {
1383 cm_msg(MERROR, "SaveRootHistograms", "Cannot create output file %s", filename);
1384 return 0;
1385 }
1386
1387 outf->cd();
1388 folder->Write();
1389 outf->Close();
1390 delete outf;
1391 // restore current directory
1392 savedir->cd();
1393 return SUCCESS;
1394}
1395
1396/*------------------------------------------------------------------*/
1397
1398// copy object from a last folder, to an online folder,
1399// and call itself to handle subfolders
1401{
1402
1403 TIter next(lastFolder->GetListOfFolders());
1404 while (TObject * obj = next()) {
1405 const char *name = obj->GetName();
1406
1407 if (obj->InheritsFrom("TFolder")) {
1408
1409 TFolder *onlineSubfolder = (TFolder *) onlineFolder->FindObject(name);
1410 if (onlineSubfolder)
1412
1413 } else if (obj->InheritsFrom("TH1")) {
1414
1415 // still don't know how to do TH1s
1416
1417 } else if (obj->InheritsFrom("TCutG")) {
1418
1419 TCutG *onlineObj = (TCutG *) onlineFolder->FindObject(name);
1420 if (onlineObj) {
1421 TCutG *lastObj = (TCutG *) obj;
1422
1423 lastObj->TAttMarker::Copy(*onlineObj);
1424 lastObj->TAttFill::Copy(*onlineObj);
1425 lastObj->TAttLine::Copy(*onlineObj);
1426 lastObj->TNamed::Copy(*onlineObj);
1427 onlineObj->Set(lastObj->GetN());
1428 for (int i = 0; i < lastObj->GetN(); ++i) {
1429 onlineObj->SetPoint(i, lastObj->GetX()[i], lastObj->GetY()[i]);
1430 }
1431 }
1432 }
1433 }
1434 return;
1435}
1436
1437/*------------------------------------------------------------------*/
1438
1439// Load all objects from given file into given directory
1440INT LoadRootHistograms(TFolder * folder, const char *filename)
1441{
1442 TFile *inf = TFile::Open(filename, "READ");
1443 if (inf == NULL)
1444 printf("Error: File \"%s\" not found\n", filename);
1445 else {
1446
1447 TFolder *lastHistos = (TFolder *) inf->Get("histos");
1448 if (lastHistos) {
1449 // copy histos to online folder
1451 inf->Close();
1452 }
1453 }
1454 return SUCCESS;
1455}
1456
1457/*------------------------------------------------------------------*/
1458
1459// Clear all TH1 objects in the given directory,
1460// and it's subdirectories
1462{
1463 TIter next(folder->GetListOfFolders());
1464 while (TObject * obj = next())
1465 if (obj->InheritsFrom("TH1"))
1466 ((TH1 *) obj)->Reset();
1467 else if (obj->InheritsFrom("TFolder"))
1469 return SUCCESS;
1470}
1471
1472/*------------------------------------------------------------------*/
1473
1475{
1476 int i;
1477
1478 // ensure that we do have an open file
1479 assert(gManaOutputFile != NULL);
1480
1481 // save the histograms
1482 gManaOutputFile->cd();
1483 gManaHistosFolder->Write();
1484
1485 // close the output file
1486 gManaOutputFile->Write();
1487 gManaOutputFile->Close();
1488 delete gManaOutputFile;
1490
1491 // delete the output trees
1492 for (i = 0; i < tree_struct.n_tree; i++)
1493 if (tree_struct.event_tree[i].branch) {
1494 free(tree_struct.event_tree[i].branch);
1495 free(tree_struct.event_tree[i].branch_name);
1496 free(tree_struct.event_tree[i].branch_filled);
1497 free(tree_struct.event_tree[i].branch_len);
1498 tree_struct.event_tree[i].branch = NULL;
1499 }
1500
1501 /* delete event tree */
1502 free(tree_struct.event_tree);
1503 tree_struct.event_tree = NULL;
1504 tree_struct.n_tree = 0;
1505
1506 // go to ROOT root directory
1507 gROOT->cd();
1508
1509 return SUCCESS;
1510}
1511
1512#endif /* HAVE_ROOT */
1513
1514/*-- analyzer init routine -----------------------------------------*/
1515
1517{
1518 ANA_MODULE **module;
1519 INT i, j, status, size;
1520 HNDLE hkey;
1521 char str[256], block_name[32];
1522 BANK_LIST *bank_list;
1523 double dummy;
1524
1525 sprintf(str, "/%s/Output", analyzer_name);
1526 db_find_key(hDB, 0, str, &hkey);
1527
1528 if (clp.online) {
1529 status =
1531 if (status != DB_SUCCESS) {
1532 cm_msg(MERROR, "bor", "Cannot read output info record");
1533 return 0;
1534 }
1535 }
1536
1537 /* create ODB structures for banks */
1538 for (i = 0; analyze_request[i].event_name[0]; i++) {
1539 bank_list = analyze_request[i].bank_list;
1540
1541 if (bank_list == NULL)
1542 continue;
1543
1544 for (; bank_list->name[0]; bank_list++) {
1545 strncpy(block_name, bank_list->name, 4);
1546 block_name[4] = 0;
1547
1548 if (bank_list->type == TID_STRUCT) {
1549 sprintf(str, "/Equipment/%s/Variables/%s", analyze_request[i].event_name,
1550 block_name);
1551 db_check_record(hDB, 0, str, strcomb1((const char **)bank_list->init_str).c_str(), TRUE);
1552 db_find_key(hDB, 0, str, &hkey);
1553 bank_list->def_key = hkey;
1554 } else {
1555 sprintf(str, "/Equipment/%s/Variables/%s", analyze_request[i].event_name,
1556 block_name);
1557 status = db_find_key(hDB, 0, str, &hkey);
1558 if (status != DB_SUCCESS) {
1559 dummy = 0;
1560 db_set_value(hDB, 0, str, &dummy, rpc_tid_size(bank_list->type), 1,
1561 bank_list->type);
1562 }
1563 bank_list->def_key = hkey;
1564 }
1565 }
1566 }
1567
1568 /* create ODB structures for fixed events */
1569 for (i = 0; analyze_request[i].event_name[0]; i++) {
1570 if (analyze_request[i].init_string) {
1571 sprintf(str, "/Equipment/%s/Variables", analyze_request[i].event_name);
1572 db_check_record(hDB, 0, str, strcomb1((const char **)analyze_request[i].init_string).c_str(), TRUE);
1573 }
1574 }
1575
1576 /* delete tests in ODB */
1577 sprintf(str, "/%s/Tests", analyzer_name);
1578 db_find_key(hDB, 0, str, &hkey);
1579 if (hkey)
1581
1582#ifdef HAVE_HBOOK
1583 /* create global memory */
1584 if (clp.online) {
1585 /* book online N-tuples only once when online */
1586 status = book_ntuples();
1587 if (status != SUCCESS)
1588 return status;
1589 } else {
1590 if (equal_ustring(clp.output_file_name, "OFLN")) {
1591 /* book online N-tuples only once when online */
1592 status = book_ntuples();
1593 if (status != SUCCESS)
1594 return status;
1595 }
1596 }
1597#endif /* HAVE_HBOOK */
1598
1599#ifdef HAVE_ROOT
1600 if (clp.online) {
1601 /* book online N-tuples only once when online */
1602 status = book_ttree();
1603 if (status != SUCCESS)
1604 return status;
1605 }
1606#endif
1607
1608 /* call main analyzer init routine */
1610 if (status != SUCCESS)
1611 return status;
1612
1613 /* initialize modules */
1614 for (i = 0; analyze_request[i].event_name[0]; i++) {
1615 module = analyze_request[i].ana_module;
1616 for (j = 0; module != NULL && module[j] != NULL; j++) {
1617
1618 /* copy module enabled flag to ana_module */
1619 sprintf(str, "/%s/Module switches/%s", analyzer_name, module[j]->name);
1620 module[j]->enabled = TRUE;
1621 size = sizeof(BOOL);
1622 db_get_value(hDB, 0, str, &module[j]->enabled, &size, TID_BOOL, TRUE);
1623
1624 if (module[j]->init != NULL && module[j]->enabled) {
1625
1626#ifdef HAVE_ROOT
1627 /* create histo subfolder for module */
1628 sprintf(str, "Histos for module %s", module[j]->name);
1629 module[j]->histo_folder = (TFolder *) gROOT->FindObjectAny(module[j]->name);
1630 if (!module[j]->histo_folder)
1631 module[j]->histo_folder =
1632 gManaHistosFolder->AddFolder(module[j]->name, str);
1633 else if (strcmp(((TObject *) module[j]->histo_folder)->ClassName(), "TFolder")
1634 != 0) {
1635 cm_msg(MERROR, "mana_init",
1636 "Fatal error: ROOT Object \"%s\" of class \"%s\" exists but it is not a TFolder, exiting!",
1637 module[j]->name,
1638 ((TObject *) module[j]->histo_folder)->ClassName());
1639 exit(1);
1640 }
1641 gHistoFolderStack->Clear();
1642 gHistoFolderStack->Add((TObject *) module[j]->histo_folder);
1643#endif
1644
1645 module[j]->init();
1646 }
1647 }
1648 }
1649
1650 return SUCCESS;
1651}
1652
1653/*-- exit routine --------------------------------------------------*/
1654
1656{
1657 ANA_MODULE **module;
1658 INT i, j;
1659
1660 /* call exit routines from modules */
1661 for (i = 0; analyze_request[i].event_name[0]; i++) {
1662 module = analyze_request[i].ana_module;
1663 for (j = 0; module != NULL && module[j] != NULL; j++)
1664 if (module[j]->exit != NULL && module[j]->enabled) {
1665 module[j]->exit();
1666 }
1667 }
1668
1669 /* call main analyzer exit routine */
1670 return analyzer_exit();
1671}
1672
1673/*-- BOR routine ---------------------------------------------------*/
1674
1675INT bor(INT run_number, char *error)
1676{
1677 ANA_MODULE **module;
1678 INT i, j, size;
1679 char str[256], file_name[256], *ext_str;
1680 BANK_LIST *bank_list;
1681
1682 /* load parameters */
1684
1685 for (i = 0; analyze_request[i].event_name[0]; i++) {
1686 /* copy output flag from ODB to bank_list */
1687 bank_list = analyze_request[i].bank_list;
1688
1689 if (bank_list != NULL)
1690 for (; bank_list->name[0]; bank_list++) {
1691 sprintf(str, "/%s/Bank switches/%s", analyzer_name, bank_list->name);
1692 bank_list->output_flag = FALSE;
1693 size = sizeof(DWORD);
1694 db_get_value(hDB, 0, str, &bank_list->output_flag, &size, TID_DWORD, TRUE);
1695 }
1696
1697 /* copy module enabled flag to ana_module */
1698 module = analyze_request[i].ana_module;
1699 for (j = 0; module != NULL && module[j] != NULL; j++) {
1700 sprintf(str, "/%s/Module switches/%s", analyzer_name, module[j]->name);
1701 module[j]->enabled = TRUE;
1702 size = sizeof(BOOL);
1703 db_get_value(hDB, 0, str, &module[j]->enabled, &size, TID_BOOL, TRUE);
1704 }
1705 }
1706
1707 /* clear histos, N-tuples and tests */
1708 if (clp.online && out_info.clear_histos) {
1709#ifdef HAVE_HBOOK
1710 int hid[10000];
1711 int n;
1712
1713 for (i = 0; analyze_request[i].event_name[0]; i++)
1714 if (analyze_request[i].bank_list != NULL)
1715 if (HEXIST(analyze_request[i].ar_info.event_id))
1716 HRESET(analyze_request[i].ar_info.event_id, bstr);
1717
1718 /* get list of all histos */
1719 HIDALL(hid, n);
1720 for (i = 0; i < n; i++) {
1721 for (j = 0; j < 10000; j++)
1722 if (lock_list[j] == 0 || lock_list[j] == hid[i])
1723 break;
1724
1725 /* clear histo if not locked */
1726 if (lock_list[j] != hid[i])
1727 HRESET(hid[i], bstr);
1728 }
1729#endif /* HAVE_HBOOK */
1730
1731#ifdef HAVE_ROOT
1732 /* clear histos */
1733 if (clp.online && out_info.clear_histos)
1735#endif /* HAVE_ROOT */
1736
1737 /* clear tests */
1738 test_clear();
1739 }
1740#ifdef HAVE_ROOT
1741 if (clp.online) {
1742 /* clear all trees when online */
1743 for (i = 0; i < tree_struct.n_tree; i++)
1744 tree_struct.event_tree[i].tree->Reset();
1745 }
1746#endif
1747
1748 /* open output file if not already open (append mode) and in offline mode */
1749 if (!clp.online && out_file == NULL && !pvm_master
1750 && !equal_ustring(clp.output_file_name, "OFLN")) {
1751 if (out_info.filename[0]) {
1752 strcpy(str, out_info.filename);
1753 if (strchr(str, '%') != NULL)
1755 else
1756 strcpy(file_name, str);
1757
1758 /* check output file extension */
1759 out_gzip = FALSE;
1760 if (strchr(file_name, '.')) {
1762 while (*ext_str != '.')
1763 ext_str--;
1764
1765 if (strncmp(ext_str, ".gz", 3) == 0) {
1766 out_gzip = TRUE;
1767 ext_str--;
1768 while (*ext_str != '.' && ext_str > file_name)
1769 ext_str--;
1770 }
1771
1772 if (strncmp(ext_str, ".asc", 4) == 0)
1774 else if (strncmp(ext_str, ".mid", 4) == 0)
1776 else if (strncmp(ext_str, ".rz", 3) == 0)
1778 else if (strncmp(ext_str, ".root", 5) == 0)
1780 else {
1781 strcpy(error, "Unknown output data format. Please use file extension .asc, .mid, .rz or .root.\n");
1782 cm_msg(MERROR, "bor", "%s", error);
1783 return 0;
1784 }
1785 } else
1787
1788#ifdef HAVE_PVM
1789 /* use node name as filename if PVM slave */
1790 if (pvm_slave) {
1791 /* extract extension */
1792 if (strchr(file_name, '.')) {
1793 strcpy(str, strchr(file_name, '.') + 1);
1795 strcat(file_name, ".");
1797 } else {
1799 }
1800
1801 PVM_DEBUG("BOR: file_name = %s", file_name);
1802 }
1803#endif
1804
1805 /* open output file */
1806 if (out_format == FORMAT_HBOOK) {
1807#ifdef HAVE_HBOOK
1808 int status, lrec;
1809 char str2[80];
1810
1811 lrec = clp.lrec;
1812#ifdef extname
1813 quest_[9] = 65000;
1814#else
1815 QUEST[9] = 65000;
1816#endif
1817
1818 strcpy(str, "BSIZE");
1820 strcpy(str, "OFFLINE");
1821 strcpy(str2, "NQP");
1823 if (status != 0) {
1824 sprintf(error, "Cannot open output file %s", out_info.filename);
1825 cm_msg(MERROR, "bor", error);
1826 out_file = NULL;
1827 return 0;
1828 } else
1829 out_file = (FILE *) 1;
1830#else
1831 cm_msg(MERROR, "bor", "HBOOK support is not compiled in");
1832#endif /* HAVE_HBOOK */
1833 }
1834
1835 else if (out_format == FORMAT_ROOT) {
1836#ifdef HAVE_ROOT
1837 // ensure the output file is closed
1838 assert(gManaOutputFile == NULL);
1839
1841 new TFile(file_name, "RECREATE", "Midas Analyzer output file");
1842 if (gManaOutputFile == NULL) {
1843 sprintf(error, "Cannot open output file %s", out_info.filename);
1844 cm_msg(MERROR, "bor", "%s", error);
1845 out_file = NULL;
1846 return 0;
1847 }
1848 // make all ROOT objects created by user module bor() functions
1849 // go into the output file
1850 gManaOutputFile->cd();
1851
1852 out_file = (FILE *) 1;
1853#else
1854 cm_msg(MERROR, "bor", "ROOT support is not compiled in");
1855#endif /* HAVE_ROOT */
1856 }
1857
1858 else {
1859 if (out_gzip)
1860 out_file = (FILE *) gzopen(file_name, "wb");
1861 else
1862 if (out_format == FORMAT_ASCII)
1863 out_file = fopen(file_name, "wt");
1864 else
1865 out_file = fopen(file_name, "wb");
1866 if (out_file == NULL) {
1867 sprintf(error, "Cannot open output file %s", file_name);
1868 cm_msg(MERROR, "bor", "%s", error);
1869 return 0;
1870 }
1871 }
1872 } else
1873 out_file = NULL;
1874
1875#ifdef HAVE_HBOOK
1876 /* book N-tuples */
1877 if (out_format == FORMAT_HBOOK) {
1878 int status = book_ntuples();
1879 if (status != SUCCESS)
1880 return status;
1881 }
1882#endif /* HAVE_HBOOK */
1883
1884#ifdef HAVE_ROOT
1885 /* book ROOT TTree */
1886 if (out_format == FORMAT_ROOT) {
1887 int status = book_ttree();
1888 if (status != SUCCESS)
1889 return status;
1890 }
1891#endif /* HAVE_ROOT */
1892
1893 }
1894
1895 /* if (out_file == NULL) */
1896 /* save run number */
1898
1899 /* call bor for modules */
1900 for (i = 0; analyze_request[i].event_name[0]; i++) {
1901 module = analyze_request[i].ana_module;
1902 for (j = 0; module != NULL && module[j] != NULL; j++)
1903 if (module[j]->bor != NULL && module[j]->enabled) {
1904 module[j]->bor(run_number);
1905 }
1906 }
1907
1908 /* call main analyzer BOR routine */
1909 return ana_begin_of_run(run_number, error);
1910}
1911
1912/*-- EOR routine ---------------------------------------------------*/
1913
1914INT eor(INT run_number, char *error)
1915{
1916 ANA_MODULE **module;
1917 BANK_LIST *bank_list;
1918 INT i, j, status;
1919 char str[256], file_name[256];
1920
1921 /* call EOR routines modules */
1922 for (i = 0; analyze_request[i].event_name[0]; i++) {
1923 module = analyze_request[i].ana_module;
1924 for (j = 0; module != NULL && module[j] != NULL; j++)
1925 if (module[j]->eor != NULL && module[j]->enabled) {
1926 module[j]->eor(run_number);
1927 }
1928 }
1929
1930 /* call main analyzer BOR routine */
1932
1933 /* save histos if requested */
1934 if (out_info.histo_dump && clp.online) {
1936 if (strchr(str, '%') != NULL)
1938 else
1939 strcpy(file_name, str);
1940
1942#ifdef HAVE_HBOOK
1943 for (i = 0; i < (int) strlen(str); i++)
1944 if (isupper(str[i]))
1945 break;
1946
1947 if (i < (int) strlen(str)) {
1948 printf
1949 ("Error: Due to a limitation in HBOOK, directoy names may not contain uppercase\n");
1950 printf(" characters. Histogram saving to %s will not work.\n", str);
1951 } else {
1952 char str2[256];
1953 strcpy(str2, "NT");
1954 HRPUT(0, str, str2);
1955 }
1956#endif /* HAVE_HBOOK */
1957
1958#ifdef HAVE_ROOT
1960#endif /* HAVE_ROOT */
1961 }
1962
1963 /* close output file */
1964 if (out_file && !out_append) {
1965 if (out_format == FORMAT_HBOOK) {
1966#ifdef HAVE_HBOOK
1967 HROUT(0, i, bstr);
1968 strcpy(str, "OFFLINE");
1969 HREND(str);
1970#else
1971 cm_msg(MERROR, "eor", "HBOOK support is not compiled in");
1972#endif /* HAVE_HBOOK */
1973 } else if (out_format == FORMAT_ROOT) {
1974#ifdef HAVE_ROOT
1976#else
1977 cm_msg(MERROR, "eor", "ROOT support is not compiled in");
1978#endif /* HAVE_ROOT */
1979 } else {
1980 if (out_gzip)
1982 else
1984 }
1985
1986 out_file = NULL;
1987
1988 /* free CWNT buffer */
1989 for (i = 0; analyze_request[i].event_name[0]; i++) {
1990 bank_list = analyze_request[i].bank_list;
1991
1992 if (bank_list == NULL) {
1993 if (analyze_request[i].addr) {
1994 free(analyze_request[i].addr);
1996 }
1997 } else {
1998 for (; bank_list->name[0]; bank_list++)
1999 if (bank_list->addr) {
2000 free(bank_list->addr);
2001 bank_list->addr = NULL;
2002 }
2003 }
2004 }
2005 }
2006
2007 return status;
2008}
2009
2010/*-- transition callbacks ------------------------------------------*/
2011
2012/*-- start ---------------------------------------------------------*/
2013
2014INT tr_start(INT rn, char *error)
2015{
2016 INT status, i;
2017
2018 /* reset counters */
2019 for (i = 0; analyze_request[i].event_name[0]; i++) {
2025 }
2026
2027 status = bor(rn, error);
2028 if (status != SUCCESS)
2029 return status;
2030
2031 return SUCCESS;
2032}
2033
2034/*-- stop ----------------------------------------------------------*/
2035
2036INT tr_stop(INT rn, char *error)
2037{
2038 INT i, status, n_bytes;
2039
2040 /* wait until all events in buffers are analyzed */
2041
2042 if (rpc_is_remote())
2043 while (bm_poll_event());
2044 else
2045 for (i = 0; analyze_request[i].event_name[0]; i++) {
2046 do {
2047 bm_get_buffer_level(analyze_request[i].buffer_handle, &n_bytes);
2048 if (n_bytes > 0)
2049 cm_yield(100);
2050 } while (n_bytes > 0);
2051 }
2052
2053 /* update statistics */
2054 update_stats();
2055
2056 status = eor(rn, error);
2057 if (status != SUCCESS)
2058 return status;
2059
2060 return CM_SUCCESS;
2061}
2062
2063/*-- pause ---------------------------------------------------------*/
2064
2065INT tr_pause(INT rn, char *error)
2066{
2067 INT status;
2068
2069 status = ana_pause_run(rn, error);
2070 if (status != CM_SUCCESS)
2071 return status;
2072
2073 return CM_SUCCESS;
2074}
2075
2076/*-- resume --------------------------------------------------------*/
2077
2078INT tr_resume(INT rn, char *error)
2079{
2080 INT status;
2081
2082 status = ana_resume_run(rn, error);
2083 if (status != CM_SUCCESS)
2084 return status;
2085
2086 return CM_SUCCESS;
2087}
2088
2089/*---- ASCII output ------------------------------------------------*/
2090
2091#define STR_INC(p,base) { p+=strlen(p); \
2092 if (p > base+sizeof(base)) \
2093 cm_msg(MERROR, "STR_INC", "ASCII buffer too small"); }
2094
2095
2097{
2098 INT status, size, i, j, count;
2099 BOOL exclude;
2101 BANK_LIST *pbl;
2103 BANK *pbk;
2104 BANK32 *pbk32;
2105 BANK32A *pbk32a;
2106 void *pdata;
2107 char *pbuf, name[5], type_name[10];
2111 HNDLE hKey;
2112 KEY key;
2113 char buffer[100000];
2114 DWORD bkname;
2115 WORD bktype;
2116
2118 if (event_def == NULL)
2119 return SS_SUCCESS;
2120
2121 /* write event header */
2122 pbuf = buffer;
2123 name[4] = 0;
2124
2125 if (pevent->event_id == EVENTID_BOR)
2126 sprintf(pbuf, "%%ID BOR NR %d\n", (int) pevent->serial_number);
2127 else if (pevent->event_id == EVENTID_EOR)
2128 sprintf(pbuf, "%%ID EOR NR %d\n", (int) pevent->serial_number);
2129 else
2130 sprintf(pbuf, "%%ID %d TR %d NR %d\n", pevent->event_id, pevent->trigger_mask,
2131 (int) pevent->serial_number);
2132 STR_INC(pbuf, buffer);
2133
2134 /*---- MIDAS format ----------------------------------------------*/
2135 if (event_def->format == FORMAT_MIDAS) {
2136 pbh = (BANK_HEADER *) (pevent + 1);
2137 pbk = NULL;
2138 pbk32 = NULL;
2139 pbk32a = NULL;
2140 do {
2141 /* scan all banks */
2142 if (bk_is32a(pbh)) {
2143 size = bk_iterate32a(pbh, &pbk32a, &pdata);
2144 if (pbk32a == NULL)
2145 break;
2146 bkname = *((DWORD *) pbk32a->name);
2147 bktype = (WORD) pbk32a->type;
2148 } else if (bk_is32(pbh)) {
2149 size = bk_iterate32(pbh, &pbk32, &pdata);
2150 if (pbk32 == NULL)
2151 break;
2152 bkname = *((DWORD *) pbk32->name);
2153 bktype = (WORD) pbk32->type;
2154 } else {
2155 size = bk_iterate(pbh, &pbk, &pdata);
2156 if (pbk == NULL)
2157 break;
2158 bkname = *((DWORD *) pbk->name);
2159 bktype = (WORD) pbk->type;
2160 }
2161
2162 /* look if bank is in exclude list */
2163 exclude = FALSE;
2164 pbl = NULL;
2165 if (par->bank_list != NULL)
2166 for (i = 0; par->bank_list[i].name[0]; i++)
2167 if (*((DWORD *) par->bank_list[i].name) == bkname) {
2168 pbl = &par->bank_list[i];
2169 exclude = (pbl->output_flag == 0);
2170 break;
2171 }
2172
2173 if (!exclude) {
2174 if (rpc_tid_size(bktype & 0xFF))
2175 size /= rpc_tid_size(bktype & 0xFF);
2176
2179
2180 /* write bank header */
2181 *((DWORD *) name) = bkname;
2182
2183 if ((bktype & 0xFF00) == 0)
2184 strcpy(type_name, rpc_tid_name(bktype & 0xFF));
2185 else if ((bktype & 0xFF00) == TID_LRS1882)
2186 strcpy(type_name, "LRS1882");
2187 else if ((bktype & 0xFF00) == TID_LRS1877)
2188 strcpy(type_name, "LRS1877");
2189 else if ((bktype & 0xFF00) == TID_PCOS3)
2190 strcpy(type_name, "PCOS3");
2191 else
2192 strcpy(type_name, "unknown");
2193
2194 sprintf(pbuf, "BK %s TP %s SZ %d\n", name, type_name, size);
2195 STR_INC(pbuf, buffer);
2196
2197 if (bktype == TID_STRUCT) {
2198 if (pbl == NULL)
2199 cm_msg(MERROR, "write_event_ascii", "received unknown bank %s", name);
2200 else
2201 /* write structured bank */
2202 for (i = 0;; i++) {
2203 status = db_enum_key(hDB, pbl->def_key, i, &hKey);
2205 break;
2206
2207 db_get_key(hDB, hKey, &key);
2208 sprintf(pbuf, "%s:\n", key.name);
2209 STR_INC(pbuf, buffer);
2210
2211 /* adjust for alignment */
2212 pdata =
2213 (void *) VALIGN(pdata,
2215
2216 for (j = 0; j < key.num_values; j++) {
2218 strcat(pbuf, "\n");
2219 STR_INC(pbuf, buffer);
2220 }
2221
2222 /* shift data pointer to next item */
2223 pdata = (char *) pdata + key.item_size * key.num_values;
2224 }
2225 } else {
2226 /* write variable length bank */
2227 if ((bktype & 0xFF00) == TID_LRS1877) {
2228 for (i = 0; i < size;) {
2230
2231 /* print header */
2232 sprintf(pbuf, "GA %d BF %d CN %d",
2233 lrs1877_header->geo_addr, lrs1877_header->buffer,
2234 lrs1877_header->count);
2235 strcat(pbuf, "\n");
2236 STR_INC(pbuf, buffer);
2237
2238 count = lrs1877_header->count;
2239 if (count == 0)
2240 break;
2241 for (j = 1; j < count; j++) {
2242 /* print data */
2243 sprintf(pbuf, "GA %d CH %02d ED %d DA %1.1lf",
2244 lrs1877[i].geo_addr, lrs1877[i + j].channel,
2245 lrs1877[i + j].edge, lrs1877[i + j].data * 0.5);
2246 strcat(pbuf, "\n");
2247 STR_INC(pbuf, buffer);
2248 }
2249
2250 i += count;
2251 }
2252 } else
2253 for (i = 0; i < size; i++) {
2254 if ((bktype & 0xFF00) == 0)
2255 db_sprintf(pbuf, pdata, size, i, bktype & 0xFF);
2256
2257 else if ((bktype & 0xFF00) == TID_LRS1882)
2258 sprintf(pbuf, "GA %d CH %02d DA %d",
2259 lrs1882[i].geo_addr, lrs1882[i].channel, lrs1882[i].data);
2260
2261 else if ((bktype & 0xFF00) == TID_PCOS3)
2262 sprintf(pbuf, "TBD");
2263 else
2264 db_sprintf(pbuf, pdata, size, i, bktype & 0xFF);
2265
2266 strcat(pbuf, "\n");
2267 STR_INC(pbuf, buffer);
2268 }
2269 }
2270 }
2271
2272 } while (1);
2273 }
2274
2275 /*---- FIXED format ----------------------------------------------*/
2276 if (event_def->format == FORMAT_FIXED) {
2277 if (event_def->hDefKey == 0)
2278 cm_msg(MERROR, "write_event_ascii", "cannot find event definition");
2279 else {
2280 pdata = (char *) (pevent + 1);
2281 for (i = 0;; i++) {
2282 status = db_enum_key(hDB, event_def->hDefKey, i, &hKey);
2284 break;
2285
2286 db_get_key(hDB, hKey, &key);
2287 sprintf(pbuf, "%s\n", key.name);
2288 STR_INC(pbuf, buffer);
2289
2290 /* adjust for alignment */
2292
2293 for (j = 0; j < key.num_values; j++) {
2295 strcat(pbuf, "\n");
2296 STR_INC(pbuf, buffer);
2297 }
2298
2299 /* shift data pointer to next item */
2300 pdata = (char *) pdata + key.item_size * key.num_values;
2301 }
2302 }
2303 }
2304
2305 /* insert empty line after each event */
2306 strcat(pbuf, "\n");
2307 size = strlen(buffer);
2308
2309 /* write record to device */
2310 if (out_gzip)
2311 status = gzwrite((gzFile)file, buffer, size) == size ? SS_SUCCESS : SS_FILE_ERROR;
2312 else
2313 status =
2314 fwrite(buffer, 1, size, file) == (size_t) size ? SS_SUCCESS : SS_FILE_ERROR;
2315
2316 return status;
2317}
2318
2319/*---- MIDAS output ------------------------------------------------*/
2320
2322{
2323 INT status, size = 0, i;
2324 BOOL exclude;
2326 BANK_LIST *pbl;
2328 BANK *pbk;
2329 BANK32 *pbk32;
2330 BANK32A *pbk32a;
2331 char *pdata, *pdata_copy;
2332 char *pbuf;
2335 WORD bktype;
2336 static char *buffer = NULL;
2337
2338 if (buffer == NULL)
2339 buffer = (char *) malloc(sys_max_event_size);
2340
2341 pevent_copy = (EVENT_HEADER *) ALIGN8((POINTER_T) buffer);
2342
2343 if (clp.filter) {
2344 /* use original event */
2345 size = pevent->data_size + sizeof(EVENT_HEADER);
2346 memcpy(pevent_copy, pevent, size);
2347 } else {
2348 /* copy only banks which are turned on via /analyzer/bank switches */
2349
2350 /*---- MIDAS format ----------------------------------------------*/
2351
2353 if (event_def == NULL)
2354 return SUCCESS;
2355
2356 if (event_def->format == FORMAT_MIDAS) {
2357 /* copy event header */
2358 pbuf = (char *) pevent_copy;
2359 memcpy(pbuf, pevent, sizeof(EVENT_HEADER));
2360 pbuf += sizeof(EVENT_HEADER);
2361
2362 pbh = (BANK_HEADER *) (pevent + 1);
2363
2364 if (bk_is32(pbh))
2365 bk_init32(pbuf);
2366 else
2367 bk_init(pbuf);
2368
2369 pbk = NULL;
2370 pbk32 = NULL;
2371 pbk32a = NULL;
2372 pdata_copy = pbuf;
2373 do {
2374 /* scan all banks */
2375 if (bk_is32a(pbh)) {
2376 size = bk_iterate32a(pbh, &pbk32a, &pdata);
2377 if (pbk32a == NULL)
2378 break;
2379 bkname = *((DWORD *) pbk32a->name);
2380 bktype = (WORD) pbk32a->type;
2381 bksize = pbk32a->data_size;
2382 } else if (bk_is32(pbh)) {
2383 size = bk_iterate32(pbh, &pbk32, &pdata);
2384 if (pbk32 == NULL)
2385 break;
2386 bkname = *((DWORD *) pbk32->name);
2387 bktype = (WORD) pbk32->type;
2388 bksize = pbk32->data_size;
2389 } else {
2390 size = bk_iterate(pbh, &pbk, &pdata);
2391 if (pbk == NULL)
2392 break;
2393 bkname = *((DWORD *) pbk->name);
2394 bktype = (WORD) pbk->type;
2395 bksize = pbk->data_size;
2396 }
2397
2398 /* look if bank is in exclude list */
2399 exclude = FALSE;
2400 pbl = NULL;
2401 if (par->bank_list != NULL)
2402 for (i = 0; par->bank_list[i].name[0]; i++)
2403 if (*((DWORD *) par->bank_list[i].name) == bkname) {
2404 pbl = &par->bank_list[i];
2405 exclude = (pbl->output_flag == 0);
2406 break;
2407 }
2408
2409 if (!exclude) {
2410 /* copy bank */
2411 bk_create(pbuf, (char *) (&bkname), bktype, (void **)&pdata_copy);
2413 pdata_copy += bksize;
2415 }
2416
2417 } while (1);
2418
2419 /* set event size in header */
2421 pevent_copy->data_size = size;
2422 size += sizeof(EVENT_HEADER);
2423 }
2424
2425 /*---- FIXED format ----------------------------------------------*/
2426 if (event_def->format == FORMAT_FIXED) {
2427 size = pevent->data_size + sizeof(EVENT_HEADER);
2428 memcpy(pevent_copy, pevent, size);
2429 }
2430
2431 if (pevent_copy->data_size == 0)
2432 return SUCCESS;
2433 }
2434
2435 /* write record to device */
2436 if (out_gzip)
2437 status = gzwrite((gzFile)file, pevent_copy, size) == size ? SUCCESS : SS_FILE_ERROR;
2438 else
2439 status =
2440 fwrite(pevent_copy, 1, size, file) == (size_t) size ? SUCCESS : SS_FILE_ERROR;
2441
2442 return status;
2443}
2444
2445/*---- HBOOK output ------------------------------------------------*/
2446
2447#ifdef HAVE_HBOOK
2448
2450{
2451 INT i, j, k, n, size, item_size, status;
2452 BANK *pbk;
2453 BANK32 *pbk32;
2454 BANK32A *pbk32a;
2455 BANK_LIST *pbl;
2457 char *pdata;
2459 char block_name[5], str[80];
2460 float rwnt[512];
2462 HNDLE hkey;
2463 KEY key;
2464 DWORD bkname;
2465 WORD bktype;
2466
2467 /* return if N-tuples are disabled */
2468 if (!ntuple_flag)
2469 return SS_SUCCESS;
2470
2472 if (event_def == NULL)
2473 return SS_SUCCESS;
2474
2475 if (event_def->disabled)
2476 return SS_SUCCESS;
2477
2478 /* fill number info */
2479 if (clp.rwnt) {
2480 memset(rwnt, 0, sizeof(rwnt));
2482 rwnt[1] = (float) pevent->serial_number;
2483 rwnt[2] = (float) pevent->time_stamp;
2484 } else {
2485 par->number.run = current_run_number;
2486 par->number.serial = pevent->serial_number;
2487 par->number.time = pevent->time_stamp;
2488 }
2489
2490 /*---- MIDAS format ----------------------------------------------*/
2491
2492 if (event_def->format == FORMAT_MIDAS) {
2493 /* first fill number block */
2494 strcpy(str, "Number");
2495 if (!clp.rwnt)
2496 HFNTB(pevent->event_id, str);
2497
2498 pbk = NULL;
2499 pbk32 = NULL;
2500 pbk32a = NULL;
2501 exclude_all = TRUE;
2502 do {
2503 pbh = (BANK_HEADER *) (pevent + 1);
2504 /* scan all banks */
2505 if (bk_is32a(pbh)) {
2506 size = bk_iterate32a(pbh, &pbk32a, &pdata);
2507 if (pbk32a == NULL)
2508 break;
2509 bkname = *((DWORD *) pbk32a->name);
2510 bktype = (WORD) pbk32a->type;
2511 } else if (bk_is32(pbh)) {
2512 size = bk_iterate32(pbh, &pbk32, &pdata);
2513 if (pbk32 == NULL)
2514 break;
2515 bkname = *((DWORD *) pbk32->name);
2516 bktype = (WORD) pbk32->type;
2517 } else {
2518 size = bk_iterate(pbh, &pbk, &pdata);
2519 if (pbk == NULL)
2520 break;
2521 bkname = *((DWORD *) pbk->name);
2522 bktype = (WORD) pbk->type;
2523 }
2524
2525 /* look if bank is in exclude list */
2526 *((DWORD *) block_name) = bkname;
2527 block_name[4] = 0;
2528
2529 exclude = FALSE;
2530 pbl = NULL;
2531 if (par->bank_list != NULL) {
2532 for (i = 0; par->bank_list[i].name[0]; i++)
2533 if (*((DWORD *) par->bank_list[i].name) == bkname) {
2534 pbl = &par->bank_list[i];
2535 exclude = (pbl->output_flag == 0);
2536 break;
2537 }
2538 if (par->bank_list[i].name[0] == 0)
2539 cm_msg(MERROR, "write_event_hbook", "Received unknown bank %s",
2540 block_name);
2541 }
2542
2543 /* fill CW N-tuple */
2544 if (!exclude && pbl != NULL && !clp.rwnt) {
2545 /* set array size in bank list */
2546 if ((bktype & 0xFF) != TID_STRUCT) {
2547 item_size = rpc_tid_size(bktype & 0xFF);
2548 if (item_size == 0) {
2549 cm_msg(MERROR, "write_event_hbook",
2550 "Received bank %s with unknown item size", block_name);
2551 continue;
2552 }
2553
2554 pbl->n_data = size / item_size;
2555
2556 /* check bank size */
2557 if (pbl->n_data > pbl->size) {
2558 cm_msg(MERROR, "write_event_hbook",
2559 "Bank %s has more (%d) entries than maximum value (%d)",
2560 block_name, pbl->n_data, pbl->size);
2561 continue;
2562 }
2563
2564 /* copy bank to buffer in bank list, DWORD aligned */
2565 if (item_size >= 4) {
2566 size = MIN((INT) pbl->size * item_size, size);
2567 memcpy(pbl->addr, pdata, size);
2568 } else if (item_size == 2)
2569 for (i = 0; i < (INT) pbl->n_data; i++)
2570 *((DWORD *) pbl->addr + i) = (DWORD) * ((WORD *) pdata + i);
2571 else if (item_size == 1)
2572 for (i = 0; i < (INT) pbl->n_data; i++)
2573 *((DWORD *) pbl->addr + i) = (DWORD) * ((BYTE *) pdata + i);
2574 } else {
2575 /* hope that structure members are aligned as HBOOK thinks ... */
2576 memcpy(pbl->addr, pdata, size);
2577 }
2578
2579 /* fill N-tuple */
2580 HFNTB(pevent->event_id, block_name);
2581 }
2582
2583 /* fill RW N-tuple */
2584 if (!exclude && pbl != NULL && clp.rwnt) {
2586
2587 item_size = rpc_tid_size(bktype & 0xFF);
2588 /* set array size in bank list */
2589 if ((bktype & 0xFF) != TID_STRUCT) {
2590 n = size / item_size;
2591
2592 /* check bank size */
2593 if (n > (INT) pbl->size) {
2594 cm_msg(MERROR, "write_event_hbook",
2595 "Bank %s has more (%d) entries than maximum value (%d)",
2596 block_name, n, pbl->size);
2597 continue;
2598 }
2599
2600 /* convert bank to float values */
2601 for (i = 0; i < n; i++) {
2602 switch (bktype & 0xFF) {
2603 case TID_BYTE:
2604 rwnt[pbl->n_data + i] = (float) (*((BYTE *) pdata + i));
2605 break;
2606 case TID_WORD:
2607 rwnt[pbl->n_data + i] = (float) (*((WORD *) pdata + i));
2608 break;
2609 case TID_DWORD:
2610 rwnt[pbl->n_data + i] = (float) (*((DWORD *) pdata + i));
2611 break;
2612 case TID_FLOAT:
2613 rwnt[pbl->n_data + i] = (float) (*((float *) pdata + i));
2614 break;
2615 case TID_DOUBLE:
2616 rwnt[pbl->n_data + i] = (float) (*((double *) pdata + i));
2617 break;
2618 }
2619 }
2620
2621 /* zero padding */
2622 for (; i < (INT) pbl->size; i++)
2623 rwnt[pbl->n_data + i] = 0.f;
2624 } else {
2625 /* fill N-tuple from structured bank */
2626 k = pbl->n_data;
2627
2628 for (i = 0;; i++) {
2629 status = db_enum_key(hDB, pbl->def_key, i, &hkey);
2631 break;
2632
2633 db_get_key(hDB, hkey, &key);
2634
2635 /* align data pointer */
2636 pdata =
2638
2639 for (j = 0; j < key.num_values; j++) {
2640 switch (key.type & 0xFF) {
2641 case TID_BYTE:
2642 rwnt[k++] = (float) (*((BYTE *) pdata + j));
2643 break;
2644 case TID_WORD:
2645 rwnt[k++] = (float) (*((WORD *) pdata + j));
2646 break;
2647 case TID_SHORT:
2648 rwnt[k++] = (float) (*((short int *) pdata + j));
2649 break;
2650 case TID_INT:
2651 rwnt[k++] = (float) (*((INT *) pdata + j));
2652 break;
2653 case TID_DWORD:
2654 rwnt[k++] = (float) (*((DWORD *) pdata + j));
2655 break;
2656 case TID_BOOL:
2657 rwnt[k++] = (float) (*((BOOL *) pdata + j));
2658 break;
2659 case TID_FLOAT:
2660 rwnt[k++] = (float) (*((float *) pdata + j));
2661 break;
2662 case TID_DOUBLE:
2663 rwnt[k++] = (float) (*((double *) pdata + j));
2664 break;
2665 }
2666 }
2667
2668 /* shift data pointer to next item */
2669 pdata += key.item_size * key.num_values * sizeof(char);
2670 }
2671 }
2672 }
2673
2674 } while (TRUE);
2675
2676 /* fill RW N-tuple */
2677 if (clp.rwnt && file != NULL && !exclude_all)
2678 HFN(pevent->event_id, rwnt);
2679
2680 /* fill shared memory */
2681 if (file == NULL)
2682 HFNOV(pevent->event_id, rwnt);
2683
2684 }
2685
2686
2687 /* if (event_def->format == FORMAT_MIDAS) */
2688 /*---- YBOS format ----------------------------------------------*/
2689 else if (event_def->format == FORMAT_YBOS) {
2690 assert(!"YBOS not supported anymore");
2691 }
2692
2693
2694 /*---- FIXED format ----------------------------------------------*/
2695 if (event_def->format == FORMAT_FIXED) {
2696 if (clp.rwnt) {
2697 /* fill N-tuple from structured bank */
2698 pdata = (char *) (pevent + 1);
2699 k = 3; /* index 0..2 for run/serial/time */
2700
2701 for (i = 0;; i++) {
2702 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
2704 break;
2705
2706 db_get_key(hDB, hkey, &key);
2707
2708 /* align data pointer */
2710
2711 for (j = 0; j < key.num_values; j++) {
2712 switch (key.type & 0xFF) {
2713 case TID_BYTE:
2714 rwnt[k++] = (float) (*((BYTE *) pdata + j));
2715 break;
2716 case TID_WORD:
2717 rwnt[k++] = (float) (*((WORD *) pdata + j));
2718 break;
2719 case TID_SHORT:
2720 rwnt[k++] = (float) (*((short int *) pdata + j));
2721 break;
2722 case TID_INT:
2723 rwnt[k++] = (float) (*((INT *) pdata + j));
2724 break;
2725 case TID_DWORD:
2726 rwnt[k++] = (float) (*((DWORD *) pdata + j));
2727 break;
2728 case TID_BOOL:
2729 rwnt[k++] = (float) (*((BOOL *) pdata + j));
2730 break;
2731 case TID_FLOAT:
2732 rwnt[k++] = (float) (*((float *) pdata + j));
2733 break;
2734 case TID_DOUBLE:
2735 rwnt[k++] = (float) (*((double *) pdata + j));
2736 break;
2737 }
2738 }
2739
2740 /* shift data pointer to next item */
2741 pdata += key.item_size * key.num_values * sizeof(char);
2742 }
2743
2744 /* fill RW N-tuple */
2745 if (file != NULL)
2746 HFN(pevent->event_id, rwnt);
2747
2748 /* fill shared memory */
2749 if (file == NULL)
2750 HFNOV(pevent->event_id, rwnt);
2751 } else {
2752 memcpy(par->addr, pevent + 1, pevent->data_size);
2753
2754 /* fill N-tuple */
2755 HFNT(pevent->event_id);
2756 }
2757
2758 }
2759
2760 return SUCCESS;
2761}
2762#endif /* HAVE_HBOOK */
2763
2764/*---- ROOT output -------------------------------------------------*/
2765
2766#ifdef HAVE_ROOT
2767
2769{
2770 INT i, bklen;
2771 BANK *pbk;
2772 BANK32 *pbk32;
2773 BANK32A *pbk32a;
2774 BANK_LIST *pbl;
2776 void *pdata;
2778 char bank_name[5];
2780 DWORD bkname;
2781 WORD bktype;
2782 EVENT_TREE *et;
2783 TBranch *branch;
2784
2785 /* return if N-tuples are disabled */
2786 if (!ntuple_flag)
2787 return SS_SUCCESS;
2788
2790 if (event_def == NULL)
2791 return SS_SUCCESS;
2792
2793 if (event_def->disabled)
2794 return SS_SUCCESS;
2795
2796 /* fill number info */
2797 par->number.run = current_run_number;
2798 par->number.serial = pevent->serial_number;
2799 par->number.time = pevent->time_stamp;
2800
2801 /*---- MIDAS format ----------------------------------------------*/
2802
2803 if (event_def->format == FORMAT_MIDAS) {
2804 /* find event in tree structure */
2805 for (i = 0; i < tree_struct.n_tree; i++)
2806 if (tree_struct.event_tree[i].event_id == pevent->event_id)
2807 break;
2808
2809 if (i == tree_struct.n_tree) {
2810 cm_msg(MERROR, "write_event_ttree", "Event #%d not booked by book_ttree()",
2811 pevent->event_id);
2812 return SS_INVALID_FORMAT;
2813 }
2814
2815 et = tree_struct.event_tree + i;
2816
2817 /* first mark all banks non-filled */
2818 for (i = 0; i < et->n_branch; i++)
2819 et->branch_filled[i] = FALSE;
2820
2821 /* first fill number block */
2822 et->branch_filled[0] = TRUE;
2823
2824 pbk = NULL;
2825 pbk32 = NULL;
2826 pbk32a = NULL;
2827 exclude_all = TRUE;
2828 do {
2829 pbh = (BANK_HEADER *) (pevent + 1);
2830 /* scan all banks */
2831 if (bk_is32a(pbh)) {
2833 if (pbk32a == NULL)
2834 break;
2835 bkname = *((DWORD *) pbk32a->name);
2836 bktype = (WORD) pbk32a->type;
2837 } else if (bk_is32(pbh)) {
2839 if (pbk32 == NULL)
2840 break;
2841 bkname = *((DWORD *) pbk32->name);
2842 bktype = (WORD) pbk32->type;
2843 } else {
2844 bklen = bk_iterate(pbh, &pbk, &pdata);
2845 if (pbk == NULL)
2846 break;
2847 bkname = *((DWORD *) pbk->name);
2848 bktype = (WORD) pbk->type;
2849 }
2850
2851 if (rpc_tid_size(bktype & 0xFF))
2852 bklen /= rpc_tid_size(bktype & 0xFF);
2853
2854 /* look if bank is in exclude list */
2855 *((DWORD *) bank_name) = bkname;
2856 bank_name[4] = 0;
2857
2858 exclude = FALSE;
2859 pbl = NULL;
2860 if (par->bank_list != NULL) {
2861 for (i = 0; par->bank_list[i].name[0]; i++)
2862 if (*((DWORD *) par->bank_list[i].name) == bkname) {
2863 pbl = &par->bank_list[i];
2864 exclude = (pbl->output_flag == 0);
2865 break;
2866 }
2867 if (par->bank_list[i].name[0] == 0) {
2868 cm_msg(MERROR, "write_event_ttree", "Received unknown bank %s", bank_name);
2869 continue;
2870 }
2871 }
2872
2873 /* fill leaf */
2874 if (!exclude && pbl != NULL) {
2875 for (i = 0; i < et->n_branch; i++)
2876 if (*((DWORD *) (&et->branch_name[i * NAME_LENGTH])) == bkname)
2877 break;
2878
2879 if (i == et->n_branch) {
2880 cm_msg(MERROR, "write_event_ttree", "Received unknown bank %s", bank_name);
2881 continue;
2882 }
2883
2885 branch = et->branch[i];
2886 et->branch_filled[i] = TRUE;
2887 et->branch_len[i] = bklen;
2888
2889 /* structured bank */
2890 if ((bktype & 0xFF) != TID_STRUCT) {
2891 TIter next(branch->GetListOfLeaves());
2892 TLeaf *leaf = (TLeaf *) next();
2893
2894 /* varibale length array */
2895 leaf->SetAddress(&et->branch_len[i]);
2896
2897 leaf = (TLeaf *) next();
2898 leaf->SetAddress(pdata);
2899 } else {
2900 /* hope that structure members are aligned as TTREE thinks ... */
2901 branch->SetAddress(pdata);
2902 }
2903 }
2904
2905 } while (TRUE);
2906
2907 /* check if all branches have been filled */
2908 for (i = 0; i < et->n_branch; i++)
2909 if (!et->branch_filled[i])
2910 cm_msg(MERROR, "root_write",
2911 "Bank %s booked but not received, tree cannot be filled",
2912 et->branch_name + (i * NAME_LENGTH));
2913
2914 /* delete tree if too many entries, will be obsolete with cyglic trees later */
2915#if (ROOT_VERSION_CODE < 262401)
2916 if (clp.online && et->tree->GetEntries() > par->rwnt_buffer_size)
2917 et->tree->Reset();
2918#endif
2919
2920 /* fill tree both online and offline */
2921 if (!exclude_all)
2922 et->tree->Fill();
2923
2924 } // if (event_def->format == FORMAT_MIDAS)
2925
2926 /*---- FIXED format ----------------------------------------------*/
2927
2928 if (event_def->format == FORMAT_FIXED) {
2929 /* find event in tree structure */
2930 for (i = 0; i < tree_struct.n_tree; i++)
2931 if (tree_struct.event_tree[i].event_id == pevent->event_id)
2932 break;
2933
2934 if (i == tree_struct.n_tree) {
2935 cm_msg(MERROR, "write_event_ttree", "Event #%d not booked by book_ttree()",
2936 pevent->event_id);
2937 return SS_INVALID_FORMAT;
2938 }
2939
2940 et = tree_struct.event_tree + i;
2941
2942 et->tree->GetBranch(et->branch_name)->SetAddress(pevent + 1);
2943 et->tree->Fill();
2944 }
2945
2946 return SUCCESS;
2947}
2948
2949#endif /* HAVE_ROOT */
2950
2951/*---- ODB output --------------------------------------------------*/
2952
2954{
2955 INT status, size, n_data, i;
2958 BANK *pbk;
2959 BANK32 *pbk32;
2960 BANK32A *pbk32a;
2961 void *pdata;
2962 char name[5];
2964 KEY key;
2965 DWORD bkname;
2966 WORD bktype;
2967
2969 if (event_def == NULL)
2970 return SS_SUCCESS;
2971
2972 /*---- MIDAS format ----------------------------------------------*/
2973
2974 if (event_def->format == FORMAT_MIDAS) {
2975 pbh = (BANK_HEADER *) (pevent + 1);
2976 pbk = NULL;
2977 pbk32 = NULL;
2978 pbk32a = NULL;
2979 do {
2980 /* scan all banks */
2981 if (bk_is32a(pbh)) {
2982 size = bk_iterate32a(pbh, &pbk32a, &pdata);
2983 if (pbk32a == NULL)
2984 break;
2985 bkname = *((DWORD *) pbk32a->name);
2986 bktype = (WORD) pbk32a->type;
2987 } else if (bk_is32(pbh)) {
2988 size = bk_iterate32(pbh, &pbk32, &pdata);
2989 if (pbk32 == NULL)
2990 break;
2991 bkname = *((DWORD *) pbk32->name);
2992 bktype = (WORD) pbk32->type;
2993 } else {
2994 size = bk_iterate(pbh, &pbk, &pdata);
2995 if (pbk == NULL)
2996 break;
2997 bkname = *((DWORD *) pbk->name);
2998 bktype = (WORD) pbk->type;
2999 }
3000
3001 n_data = size;
3002 if (rpc_tid_size(bktype & 0xFF))
3003 n_data /= rpc_tid_size(bktype & 0xFF);
3004
3005 /* get bank key */
3006 *((DWORD *) name) = bkname;
3007 name[4] = 0;
3008
3009 status = db_find_key(hDB, event_def->hDefKey, name, &hKeyRoot);
3010 if (status != DB_SUCCESS) {
3011 cm_msg(MERROR, "write_event_odb", "received unknown bank %s", name);
3012 continue;
3013 }
3014
3015 if (bktype == TID_STRUCT) {
3016 /* write structured bank */
3017 for (i = 0;; i++) {
3020 break;
3021
3022 db_get_key(hDB, hKey, &key);
3023
3024 /* adjust for alignment */
3025 if (key.type != TID_STRING && key.type != TID_LINK)
3026 pdata =
3028
3031 if (status != DB_SUCCESS) {
3032 cm_msg(MERROR, "write_event_odb", "cannot write %s to ODB", name);
3033 continue;
3034 }
3035
3036 /* shift data pointer to next item */
3037 pdata = (char *) pdata + key.item_size * key.num_values;
3038 }
3039 } else {
3041
3042 /* write variable length bank */
3043 if (n_data > 0) {
3044 status = db_set_data(hDB, hKeyRoot, pdata, size, n_data, key.type);
3045 if (status != DB_SUCCESS) {
3046 cm_msg(MERROR, "write_event_odb", "cannot write %s to ODB", name);
3047 continue;
3048 }
3049 }
3050 }
3051 } while (1);
3052 }
3053
3054 /*---- FIXED format ----------------------------------------------*/
3055
3056 if (event_def->format == FORMAT_FIXED && !clp.online) {
3057 if (db_set_record
3058 (hDB, event_def->hDefKey, (char *) (pevent + 1), pevent->data_size,
3059 0) != DB_SUCCESS)
3060 cm_msg(MERROR, "write_event_odb", "event #%d size mismatch", pevent->event_id);
3061 }
3062
3063 return SUCCESS;
3064}
3065
3066/*------------------------------------------------------------------*/
3067
3068static struct {
3069 short int event_id;
3072
3074
3076{
3077 if (_current_par)
3079}
3080
3082{
3083 INT i, status = SUCCESS, ch;
3084 ANA_MODULE **module;
3087 static DWORD last_time_kb = 0;
3088 static char *orig_event = NULL;
3089
3090 /* verbose output */
3091 if (clp.verbose)
3092 printf("event %d, number %d, total size %d\n",
3093 (int) pevent->event_id,
3094 (int) pevent->serial_number,
3095 (int) (pevent->data_size + sizeof(EVENT_HEADER)));
3096
3097 /* save analyze_request for event number correction */
3098 _current_par = par;
3099
3100 /* check keyboard once every second */
3102 if (!clp.online && actual_time - last_time_kb > 1000 && !clp.quiet && !pvm_slave) {
3104
3105 while (ss_kbhit()) {
3106 ch = ss_getchar(0);
3107 if (ch == -1)
3108 ch = getchar();
3109
3110 if ((char) ch == '!')
3111 return RPC_SHUTDOWN;
3112 }
3113 }
3114
3115 if (par == NULL) {
3116 /* load ODB with BOR event */
3117 if (pevent->event_id == EVENTID_BOR) {
3118 /* get run number from BOR event */
3120
3121 cm_msg(MINFO, "process_event", "Set run number %d in ODB", current_run_number);
3122 assert(current_run_number > 0);
3123
3124 /* set run number in ODB */
3125 status = db_set_value(hDB, 0, "/Runinfo/Run number", &current_run_number,
3126 sizeof(current_run_number), 1, TID_INT);
3127 assert(status == SUCCESS);
3128
3129 /* load ODB from event */
3130 odb_load(pevent);
3131
3132#ifdef HAVE_PVM
3133 PVM_DEBUG("process_event: ODB load");
3134#endif
3135 }
3136 } else
3137 /* increment event counter */
3138 par->events_received++;
3139
3140#ifdef HAVE_PVM
3141
3142 /* if master, distribute events to clients */
3143 if (pvm_master) {
3144 status = pvm_distribute(par, pevent);
3145 return status;
3146 }
3147#endif
3148
3149 /* don't analyze special (BOR,MESSAGE,...) events */
3150 if (par == NULL)
3151 return SUCCESS;
3152
3153 /* swap event if necessary */
3155 if (event_def == NULL)
3156 return 0;
3157
3158 if (event_def->format == FORMAT_MIDAS)
3159 bk_swap((BANK_HEADER *) (pevent + 1), FALSE);
3160
3161 /* keep copy of original event */
3162 if (clp.filter) {
3163 if (orig_event == NULL)
3164 orig_event = (char *) malloc(sys_max_event_size + sizeof(EVENT_HEADER));
3165 memcpy(orig_event, pevent, pevent->data_size + sizeof(EVENT_HEADER));
3166 }
3167
3168 /*---- analyze event ----*/
3169
3170 /* call non-modular analyzer if defined */
3171 if (par->analyzer) {
3172 status = par->analyzer(pevent, (void *) (pevent + 1));
3173
3174 /* don't continue if event was rejected */
3175 if (status == ANA_SKIP)
3176 return 0;
3177 }
3178
3179 /* loop over analyzer modules */
3180 module = par->ana_module;
3181 for (i = 0; module != NULL && module[i] != NULL; i++) {
3182 if (module[i]->enabled) {
3183
3184 status = module[i]->analyzer(pevent, (void *) (pevent + 1));
3185
3186 /* don't continue if event was rejected */
3187 if (status == ANA_SKIP)
3188 return 0;
3189 }
3190 }
3191
3192 if (event_def->format == FORMAT_MIDAS) {
3193 /* check if event got too large */
3194 i = bk_size(pevent + 1);
3195 if (i > sys_max_event_size)
3196 cm_msg(MERROR, "process_event", "Event got too large (%d Bytes) in analyzer", i);
3197
3198 /* correct for increased event size */
3199 pevent->data_size = i;
3200 }
3201
3202 if (event_def->format == FORMAT_YBOS) {
3203 assert(!"YBOS not supported anymore");
3204 }
3205
3206 /* increment tests */
3207 if (par->use_tests)
3209
3210 /* in filter mode, use original event */
3211 if (clp.filter)
3212 pevent = (EVENT_HEADER *) orig_event;
3213
3214 /* write resulting event */
3215 if (out_file) {
3216#ifdef HAVE_HBOOK
3217 if (out_format == FORMAT_HBOOK)
3219#endif /* HAVE_HBOOK */
3220#ifdef HAVE_ROOT
3221 if (out_format == FORMAT_ROOT)
3223#endif /* HAVE_ROOT */
3224 if (out_format == FORMAT_ASCII)
3226 if (out_format == FORMAT_MIDAS)
3228
3229 if (status != SUCCESS) {
3230 cm_msg(MERROR, "process_event", "Error writing to file (Disk full?)");
3231 return -1;
3232 }
3233
3234 par->events_written++;
3235 }
3236#ifdef HAVE_HBOOK
3237 /* fill shared memory */
3238 if ((clp.online || equal_ustring(clp.output_file_name, "OFLN"))
3239 && par->rwnt_buffer_size > 0)
3240 write_event_hbook(NULL, pevent, par);
3241#endif /* HAVE_HBOOK */
3242#ifdef HAVE_ROOT
3243 /* fill tree, should later be replaced by cyclic filling once it's implemented in ROOT */
3244 if (clp.online && par->rwnt_buffer_size > 0)
3245 write_event_ttree(NULL, pevent, par);
3246#endif
3247
3248
3249 /* put event in ODB once every second */
3251 for (i = 0; i < 50; i++) {
3252 if (last_time_event[i].event_id == pevent->event_id) {
3253 if (event_def->type == EQ_PERIODIC ||
3254 event_def->type == EQ_SLOW
3255 || actual_time - last_time_event[i].last_time > 1000) {
3256 last_time_event[i].last_time = actual_time;
3257 write_event_odb(pevent);
3258 }
3259 break;
3260 }
3261 if (last_time_event[i].event_id == 0) {
3262 last_time_event[i].event_id = pevent->event_id;
3263 last_time_event[i].last_time = actual_time;
3264 write_event_odb(pevent);
3265 break;
3266 }
3267 }
3268
3269 return SUCCESS;
3270}
3271
3272/*------------------------------------------------------------------*/
3273
3274void receive_event(HNDLE buffer_handle, HNDLE request_id, EVENT_HEADER * pheader,
3275 void *pevent)
3276/* receive online event */
3277{
3279 static DWORD buffer_size = 0;
3280 static char *buffer = NULL;
3281 char *pb;
3282
3283 if (buffer == NULL) {
3284 buffer = (char *) malloc(sys_max_event_size + sizeof(EVENT_HEADER));
3285
3286 if (buffer == NULL) {
3287 cm_msg(MERROR, "receive_event", "Not enough memory to buffer event of size %d", buffer_size);
3288 return;
3289 }
3290 }
3291
3292 /* align buffer */
3293 pb = (char *) ALIGN8((POINTER_T) buffer);
3294
3295 /* copy event to local buffer */
3296 memcpy(pb, pheader, pheader->data_size + sizeof(EVENT_HEADER));
3297
3299
3300 for (; par->event_name[0]; par++)
3301 if (par->buffer_handle == buffer_handle && par->request_id == request_id) {
3303 }
3304}
3305
3306/*------------------------------------------------------------------*/
3307
3309{
3310 AR_INFO *ar_info;
3311 INT i;
3312
3313 if (!clp.online)
3314 return;
3315
3316 /* check which request's key has changed */
3317 for (i = 0; analyze_request[i].event_name[0]; i++)
3318 if (analyze_request[i].hkey_common == hKey) {
3319 ar_info = &analyze_request[i].ar_info;
3320
3321 /* remove previous request */
3322 if (analyze_request[i].request_id != -1)
3323 bm_delete_request(analyze_request[i].request_id);
3324
3325 /* if enabled, add new request */
3326 if (ar_info->enabled)
3327 bm_request_event(analyze_request[i].buffer_handle, (short) ar_info->event_id,
3328 (short) ar_info->trigger_mask, ar_info->sampling_type,
3330 else
3332 }
3333
3334}
3335
3336/*------------------------------------------------------------------*/
3337
3339{
3340 INT index, status;
3341 char str[256];
3342 AR_INFO *ar_info;
3343 AR_STATS *ar_stats;
3344 HNDLE hKey;
3345
3346 /* scan ANALYZE_REQUEST table from ANALYZE.C */
3347 for (index = 0; analyze_request[index].event_name[0]; index++) {
3348 ar_info = &analyze_request[index].ar_info;
3349 ar_stats = &analyze_request[index].ar_stats;
3350
3351 /* create common subtree from analyze_request table in analyze.c */
3352 sprintf(str, "/%s/%s/Common", analyzer_name, analyze_request[index].event_name);
3354 db_find_key(hDB, 0, str, &hKey);
3356
3357 strcpy(ar_info->client_name, analyzer_name);
3358 auto host = ss_gethostname();
3359 strlcpy(ar_info->host, host.c_str(), sizeof(ar_info->host));
3360 db_set_record(hDB, hKey, ar_info, sizeof(AR_INFO), 0);
3361
3362 /* open hot link to analyzer request info */
3364 NULL);
3365
3366 /* create statistics tree */
3367 sprintf(str, "/%s/%s/Statistics", analyzer_name, analyze_request[index].event_name);
3369 db_find_key(hDB, 0, str, &hKey);
3370 assert(hKey);
3371
3372 ar_stats->events_received = 0;
3373 ar_stats->events_per_sec = 0;
3374 ar_stats->events_written = 0;
3375
3376 /* open hot link to statistics tree */
3377 status =
3378 db_open_record(hDB, hKey, ar_stats, sizeof(AR_STATS), MODE_WRITE, NULL, NULL);
3379 if (status != DB_SUCCESS)
3380 printf("Cannot open statistics record, probably other analyzer is using it\n");
3381
3382 if (clp.online) {
3383 /*---- open event buffer ---------------------------------------*/
3385
3386 /* set the default buffer cache size */
3387 bm_set_cache_size(analyze_request[index].buffer_handle, 100000, 0);
3388
3389 /*---- request event -------------------------------------------*/
3390 if (ar_info->enabled)
3391 bm_request_event(analyze_request[index].buffer_handle,
3392 (short) ar_info->event_id, (short) ar_info->trigger_mask,
3395 else
3397 }
3398 }
3399}
3400
3401/*------------------------------------------------------------------*/
3402
3404{
3405 int i;
3406 AR_STATS *ar_stats;
3407 static DWORD last_time = 0;
3409
3411
3412 if (last_time == 0)
3414
3415 if (actual_time - last_time == 0)
3416 return;
3417
3418 for (i = 0; analyze_request[i].event_name[0]; i++) {
3419 ar_stats = &analyze_request[i].ar_stats;
3422 ar_stats->events_per_sec =
3426 }
3427
3428 /* propagate new statistics to ODB */
3430
3431 /* save tests in ODB */
3433
3435}
3436
3437/*-- Book histos --------------------------------------------------*/
3438
3439#ifdef HAVE_ROOT
3440
3441/* h1_book and h2_book are now templates in midas.h */
3442
3443//==============================================================================
3444
3445TCutG *cut_book(const char *name)
3446{
3447
3448//------------------------------------------------------------------------------
3449
3450 open_subfolder((char *)"cuts");
3451
3454
3455 TCutG *cut((TCutG *) folder->FindObject(name));
3456
3457 if (!cut) {
3458 cut = new TCutG();
3459 cut->SetName(name);
3460 folder->Add(cut);
3461 }
3462
3464 return cut;
3465}
3466
3467void open_subfolder(const char *name)
3468{
3469
3471
3472 if (!current)
3474
3475 // if the subfolder already exists, use it
3476 TFolder *subfolder = 0;
3477
3478 TCollection *listOfSubFolders = current->GetListOfFolders();
3480 while (TObject * obj = iter()) {
3481 if (strcmp(obj->GetName(), name) == 0 && obj->InheritsFrom("TFolder"))
3482 subfolder = (TFolder *) obj;
3483 }
3484
3485 if (!subfolder) {
3486 subfolder = new TFolder(name, name);
3487 current->Add(subfolder);
3488 }
3489
3491}
3492
3493void close_subfolder()
3494{
3495 if (gHistoFolderStack->Last())
3496 gHistoFolderStack->Remove(gHistoFolderStack->Last());
3497}
3498
3499#endif
3500
3501/*-- Clear histos --------------------------------------------------*/
3502#ifdef HAVE_HBOOK
3504{
3505 INT i;
3506
3507 if (id1 != id2) {
3508 printf("Clear ID %d to ID %d\n", id1, id2);
3509 for (i = id1; i <= id2; i++)
3510 if (HEXIST(i))
3511 HRESET(i, bstr);
3512 } else {
3513 printf("Clear ID %d\n", id1);
3514 HRESET(id1, bstr);
3515 }
3516
3517 return SUCCESS;
3518}
3519#endif /* HAVE_HBOOK */
3520
3521/*------------------------------------------------------------------*/
3522
3524{
3525 INT i;
3526
3527 for (i = 0; i < 10000; i++)
3528 if (lock_list[i] == 0)
3529 break;
3530
3531 lock_list[i] = id;
3532}
3533
3534/*------------------------------------------------------------------*/
3535
3536#ifdef HAVE_HBOOK
3538{
3541 return RPC_SUCCESS;
3542}
3543#endif
3544
3545/*------------------------------------------------------------------*/
3546
3548{
3549 char str[256];
3550
3551 /* load previous online histos */
3552 if (!clp.no_load) {
3554
3555 if (strchr(str, DIR_SEPARATOR) == NULL)
3557
3558#ifdef HAVE_HBOOK
3559 {
3560 FILE *f;
3561 char str2[256];
3562 int i;
3563
3564 for (i = 0; i < (int) strlen(str); i++)
3565 if (isupper(str[i]))
3566 break;
3567
3568 if (i < (int) strlen(str)) {
3569 printf
3570 ("Error: Due to a limitation in HBOOK, directoy names may not contain uppercase\n");
3571 printf(" characters. Histogram loading from %s will not work.\n", str);
3572 } else {
3573 f = fopen(str, "r");
3574 if (f != NULL) {
3575 fclose(f);
3576 printf("Loading previous online histos from %s\n", str);
3577 strcpy(str2, "A");
3578 HRGET(0, str, str2);
3579
3580 /* fix wrongly booked N-tuples at ID 100000 */
3581 if (HEXIST(100000))
3582 HDELET(100000);
3583 }
3584 }
3585 }
3586#endif /* HAVE_HBOOK */
3587
3588#ifdef HAVE_ROOT
3589 printf("Loading previous online histos from %s\n", str);
3591#endif
3592 }
3593}
3594
3595/*------------------------------------------------------------------*/
3596
3598{
3599 char str[256];
3600
3601 /* save online histos */
3603 if (strchr(str, DIR_SEPARATOR) == NULL)
3605
3606 printf("Saving current online histos to %s\n", str);
3607
3608#ifdef HAVE_HBOOK
3609 {
3610 int i;
3611 char str2[256];
3612
3613 for (i = 0; i < (int) strlen(str); i++)
3614 if (isupper(str[i]))
3615 break;
3616
3617 if (i < (int) strlen(str)) {
3618 printf
3619 ("Error: Due to a limitation in HBOOK, directoy names may not contain uppercase\n");
3620 printf(" characters. Histogram saving to %s will not work.\n", str);
3621 } else {
3622 strcpy(str2, "NT");
3623 HRPUT(0, str, str2);
3624 }
3625 }
3626#endif
3627
3628#ifdef HAVE_ROOT
3630#endif
3631
3632}
3633
3634/*------------------------------------------------------------------*/
3635
3637{
3638 INT status = SUCCESS;
3640 int ch;
3641
3642 printf("Running analyzer online. Stop with \"!\"\n");
3643
3644 /* main loop */
3645 last_time_update = 0;
3646 last_time_loop = 0;
3647
3648 do {
3649 /* calculate events per second */
3651
3652 if (actual_time - last_time_update > 1000) {
3653 /* update statistics */
3654 update_stats();
3656
3657 /* check keyboard */
3658 ch = 0;
3659 while (ss_kbhit()) {
3660 ch = ss_getchar(0);
3661 if (ch == -1)
3662 ch = getchar();
3663
3664 if ((char) ch == '!')
3665 break;
3666 }
3667
3668 if ((char) ch == '!')
3669 break;
3670 }
3671
3672 if (analyzer_loop_period == 0)
3673 status = cm_yield(1000);
3674 else {
3677 analyzer_loop();
3678 }
3679
3681 }
3682
3683 } while (status != RPC_SHUTDOWN && status != SS_ABORT);
3684
3685 /* update statistics */
3686 update_stats();
3687
3688 return status;
3689}
3690
3691/*------------------------------------------------------------------*/
3692
3694{
3695 INT i, j, status, size;
3696 ANA_MODULE **module;
3697 char str[80];
3698 HNDLE hkey;
3699
3700 for (i = 0; analyze_request[i].event_name[0]; i++) {
3701 module = analyze_request[i].ana_module;
3702 for (j = 0; module != NULL && module[j] != NULL; j++) {
3703 if (module[j]->parameters != NULL) {
3704 sprintf(str, "/%s/Parameters/%s", analyzer_name, module[j]->name);
3705
3706 if (bclose) {
3707 db_find_key(hDB, 0, str, &hkey);
3709 } else {
3710 status = db_find_key(hDB, 0, str, &hkey);
3711 if (status == DB_SUCCESS) {
3712 db_get_record_size(hDB, hkey, 0, &size);
3713 if (size != module[j]->param_size)
3714 status = 0;
3715 }
3716 if (status != DB_SUCCESS && module[j]->init_str) {
3717 if (db_check_record(hDB, 0, str, strcomb1((const char **)module[j]->init_str).c_str(), TRUE) !=
3718 DB_SUCCESS) {
3719 cm_msg(MERROR, "init_module_parameters",
3720 "Cannot create/check \"%s\" parameters in ODB", str);
3721 return 0;
3722 }
3723 }
3724
3725 db_find_key(hDB, 0, str, &hkey);
3726 assert(hkey);
3727
3728 if (db_open_record(hDB, hkey, module[j]->parameters, module[j]->param_size,
3729 MODE_READ, NULL, NULL) != DB_SUCCESS) {
3730 cm_msg(MERROR, "init_module_parameters",
3731 "Cannot open \"%s\" parameters in ODB", str);
3732 return 0;
3733 }
3734 }
3735 }
3736 }
3737 }
3738
3739 return SUCCESS;
3740}
3741
3742/*------------------------------------------------------------------*/
3744{
3745 BOOL flag;
3746 int size, i, status;
3747 char str[256];
3749
3750 flag = TRUE;
3751 size = sizeof(flag);
3752 sprintf(str, "/%s/ODB Load", analyzer_name);
3753 db_get_value(hDB, 0, str, &flag, &size, TID_BOOL, TRUE);
3754
3755 if (flag) {
3756 for (i = 0; i < 10; i++)
3757 if (clp.protect[i][0] && !clp.quiet)
3758 printf("Protect ODB tree \"%s\"\n", clp.protect[i]);
3759
3760 if (!clp.quiet)
3761 printf("Load ODB from run %d...", (int) current_run_number);
3762
3763 if (flag == 1) {
3764 /* lock all ODB values except run parameters */
3766
3767 db_find_key(hDB, 0, "/Experiment/Run Parameters", &hKey);
3768 if (hKey)
3770
3771 /* and analyzer parameters */
3772 sprintf(str, "/%s/Parameters", analyzer_name);
3773 db_find_key(hDB, 0, str, &hKey);
3774 if (hKey)
3776
3777 /* and equipment (except /variables) */
3778 db_find_key(hDB, 0, "/Equipment", &hKeyRoot);
3779 if (hKeyRoot) {
3781
3782 for (i = 0;; i++) {
3785 break;
3786
3788
3789 db_find_key(hDB, hKeyEq, "Variables", &hKey);
3790 if (hKey)
3792 }
3793 }
3794
3795 /* lock protected trees */
3796 for (i = 0; i < 10; i++)
3797 if (clp.protect[i][0]) {
3798 db_find_key(hDB, 0, clp.protect[i], &hKey);
3799 if (hKey)
3801 }
3802 }
3803
3804 /* close open records to parameters */
3806
3807 if (strncmp((char *) (pevent + 1), "<?xml version=\"1.0\"", 19) == 0)
3808 db_paste_xml(hDB, 0, (char *) (pevent + 1));
3809 else
3810 db_paste(hDB, 0, (char *) (pevent + 1));
3811
3812 if (flag == 1)
3814
3815 /* reinit structured opened by user analyzer */
3816 analyzer_init();
3817
3818 /* reload parameter files after BOR event */
3819 if (!clp.quiet)
3820 printf("OK\n");
3822
3823 /* open module parameters again */
3825 }
3826}
3827
3828/*------------------------------------------------------------------*/
3829
3830#define MA_DEVICE_DISK 1
3831#define MA_DEVICE_TAPE 2
3832#define MA_DEVICE_FTP 3
3833#define MA_DEVICE_PVM 4
3834
3835#define MA_FORMAT_MIDAS (1<<0)
3836#define MA_FORMAT_YBOS (1<<2)
3837#define MA_FORMAT_GZIP (1<<3)
3838
3839typedef struct {
3840 char file_name[256];
3843 int fd;
3845 char *buffer;
3846 int wp, rp;
3847 /*FTP_CON ftp_con; */
3848} MA_FILE;
3849
3850/*------------------------------------------------------------------*/
3851
3853{
3854 char *ext_str;
3855 MA_FILE *file;
3856
3857 /* allocate MA_FILE structure */
3858 file = (MA_FILE *) calloc(sizeof(MA_FILE), 1);
3859 if (file == NULL) {
3860 cm_msg(MERROR, "ma_open", "Cannot allocate MA file structure");
3861 return NULL;
3862 }
3863
3864 /* save file name */
3865 strcpy(file->file_name, file_name);
3866
3867 /* for now, just read from disk */
3868 file->device = MA_DEVICE_DISK;
3869
3870 /* or from PVM */
3871 if (pvm_slave) {
3872 file->device = MA_DEVICE_PVM;
3873 file->buffer = (char *) malloc(PVM_BUFFER_SIZE);
3874 file->wp = file->rp = 0;
3875 }
3876
3877 /* check input file extension */
3878 if (strchr(file_name, '.')) {
3880 while (*ext_str != '.')
3881 ext_str--;
3882 } else
3883 ext_str = (char *)"";
3884
3885 if (strncmp(ext_str, ".gz", 3) == 0) {
3886 ext_str--;
3887 while (*ext_str != '.' && ext_str > file_name)
3888 ext_str--;
3889 }
3890
3891 if (strncmp(file_name, "/dev/", 4) == 0) /* assume MIDAS tape */
3892 file->format = MA_FORMAT_MIDAS;
3893 else if (strncmp(ext_str, ".mid", 4) == 0)
3894 file->format = MA_FORMAT_MIDAS;
3895 else if (strncmp(ext_str, ".ybs", 4) == 0)
3896 assert(!"YBOS not supported anymore");
3897 else {
3898 printf
3899 ("Unknown input data format \"%s\". Please use file extension .mid or mid.gz.\n",
3900 ext_str);
3901 return NULL;
3902 }
3903
3904 if (file->device == MA_DEVICE_DISK) {
3905 if (file->format == MA_FORMAT_YBOS) {
3906 assert(!"YBOS not supported anymore");
3907 } else {
3908 file->gzfile = gzopen(file_name, "rb");
3909 if (file->gzfile == NULL)
3910 return NULL;
3911 }
3912 }
3913
3914 return file;
3915}
3916
3917/*------------------------------------------------------------------*/
3918
3920{
3921 if (file->format == MA_FORMAT_YBOS)
3922 assert(!"YBOS not supported anymore");
3923 else
3924 gzclose((gzFile)file->gzfile);
3925
3926 free(file);
3927 return SUCCESS;
3928}
3929
3930/*------------------------------------------------------------------*/
3931
3932int ma_read_event(MA_FILE * file, EVENT_HEADER * pevent, int size)
3933{
3934 int n;
3935
3936 if (file->device == MA_DEVICE_DISK) {
3937 if (file->format == MA_FORMAT_MIDAS) {
3938 if (size < (int) sizeof(EVENT_HEADER)) {
3939 cm_msg(MERROR, "ma_read_event", "Buffer size too small");
3940 return -1;
3941 }
3942
3943 /* read event header */
3944 n = gzread(file->gzfile, pevent, sizeof(EVENT_HEADER));
3945
3946 if (n < (int) sizeof(EVENT_HEADER)) {
3947 if (n > 0)
3948 printf("Unexpected end of file %s, last event skipped\n", file->file_name);
3949 return -1;
3950 }
3951
3952 /* swap event header if in wrong format */
3953#ifdef SWAP_EVENTS
3954 WORD_SWAP(&pevent->event_id);
3955 WORD_SWAP(&pevent->trigger_mask);
3956 DWORD_SWAP(&pevent->serial_number);
3957 DWORD_SWAP(&pevent->time_stamp);
3958 DWORD_SWAP(&pevent->data_size);
3959#endif
3960
3961 /* read event */
3962 n = 0;
3963 if (pevent->data_size > 0) {
3964 if (size < (int) pevent->data_size + (int) sizeof(EVENT_HEADER)) {
3965 cm_msg(MERROR, "ma_read_event", "Buffer size too small");
3966 return -1;
3967 }
3968 n = gzread(file->gzfile, pevent + 1, pevent->data_size);
3969 if (n != (INT) pevent->data_size) {
3970 printf("Unexpected end of file %s, last event skipped\n", file->file_name);
3971 return -1;
3972 }
3973 }
3974
3975 return n + sizeof(EVENT_HEADER);
3976 } else if (file->format == MA_FORMAT_YBOS) {
3977 assert(!"YBOS not supported anymore");
3978 }
3979 } else if (file->device == MA_DEVICE_PVM) {
3980#ifdef HAVE_PVM
3981 int bufid, len, tag, tid;
3983 struct timeval timeout;
3984
3985 /* check if anything in buffer */
3986 if (file->wp > file->rp) {
3987 pe = (EVENT_HEADER *) (file->buffer + file->rp);
3988 size = sizeof(EVENT_HEADER) + pe->data_size;
3989 memcpy(pevent, pe, size);
3990 file->rp += size;
3991 return size;
3992 }
3993
3994 /* send data request */
3997
3998 /* receive data */
3999 timeout.tv_sec = 60;
4000 timeout.tv_usec = 0;
4001
4002 bufid = pvm_trecv(-1, -1, &timeout);
4003 if (bufid < 0) {
4004 pvm_perror("pvm_recv");
4005 return -1;
4006 }
4007 if (bufid == 0) {
4008 PVM_DEBUG("ma_read_event: timeout receiving data, aborting analyzer.\n");
4009 return -1;
4010 }
4011
4012 status = pvm_bufinfo(bufid, &len, &tag, &tid);
4013 if (status < 0) {
4014 pvm_perror("pvm_bufinfo");
4015 return -1;
4016 }
4017
4018 PVM_DEBUG("ma_read_event: receive tag %d, buflen %d", tag, len);
4019
4020 if (tag == TAG_EOR || tag == TAG_EXIT)
4021 return -1;
4022
4023 file->wp = len;
4024 file->rp = 0;
4025 status = pvm_upkbyte((char *) file->buffer, len, 1);
4026 if (status < 0) {
4027 pvm_perror("pvm_upkbyte");
4028 return -1;
4029 }
4030
4031 /* no new data available, sleep some time to reduce network traffic */
4032 if (len == 0)
4033 ss_sleep(200);
4034
4035 /* re-call this function */
4036 return ma_read_event(file, pevent, size);
4037#endif
4038 }
4039
4040 return 0;
4041}
4042
4043/*------------------------------------------------------------------*/
4044
4046{
4049 INT n, size;
4051 char error[256], str[256];
4052 INT status = SUCCESS;
4053 MA_FILE *file;
4054 BOOL skip;
4055 DWORD start_time;
4056
4057 /* set output file name and flags in ODB */
4058 sprintf(str, "/%s/Output/Filename", analyzer_name);
4060#ifdef HAVE_HBOOK
4061 sprintf(str, "/%s/Output/RWNT", analyzer_name);
4062 db_set_value(hDB, 0, str, &clp.rwnt, sizeof(BOOL), 1, TID_BOOL);
4063#endif
4064
4065 assert(run_number > 0);
4066
4067 /* set run number in ODB */
4068 status = db_set_value(hDB, 0, "/Runinfo/Run number", &run_number, sizeof(run_number), 1, TID_INT);
4069 assert(status == SUCCESS);
4070
4071 /* set file name in out_info */
4073
4074 /* let changes propagate to modules */
4075 cm_yield(0);
4076
4077 /* open input file, will be changed to ma_open_file later... */
4079 if (file == NULL) {
4080 printf("Cannot open input file \"%s\"\n", input_file_name);
4081 return -1;
4082 }
4083
4085
4087 if (pevent_unaligned == NULL) {
4088 printf("Not enough memeory\n");
4089 return -1;
4090 }
4092
4093 /* call analyzer bor routines */
4094 bor(run_number, error);
4095
4097
4098 start_time = ss_millitime();
4099
4100 /* event loop */
4101 do {
4102 /* read next event */
4103 n = ma_read_event(file, pevent, ext_event_size);
4104 if (n <= 0)
4105 break;
4106
4107 num_events_in++;
4108
4109 /* copy system events (BOR, EOR, MESSAGE) to output file */
4110 if (pevent->event_id < 0) {
4111 status = process_event(NULL, pevent);
4112 if (status < 0 || status == RPC_SHUTDOWN) /* disk full/stop analyzer */
4113 break;
4114
4115 if (out_file && out_format == FORMAT_MIDAS) {
4116 size = pevent->data_size + sizeof(EVENT_HEADER);
4117 if (out_gzip)
4118 status = gzwrite((gzFile)out_file, pevent, size) == size ? SUCCESS : SS_FILE_ERROR;
4119 else
4120 status =
4121 fwrite(pevent, 1, size,
4122 out_file) == (size_t) size ? SUCCESS : SS_FILE_ERROR;
4123
4124 if (status != SUCCESS) {
4125 cm_msg(MERROR, "analyze_run", "Error writing to file (Disk full?)");
4126 return -1;
4127 }
4128
4130 }
4131
4132 /* reinit start time after BOR event */
4133 if (pevent->event_id == EVENTID_BOR)
4134 start_time = ss_millitime();
4135 }
4136
4137 /* check if event is in event limit */
4138 skip = FALSE;
4139
4140 if (!pvm_slave) {
4141 if (clp.n[0] > 0 || clp.n[1] > 0) {
4142 if (clp.n[1] == 0) {
4143 /* treat n[0] as upper limit */
4144 if (num_events_in > clp.n[0]) {
4145 num_events_in--;
4146 status = SUCCESS;
4147 break;
4148 }
4149 } else {
4150 if (num_events_in > clp.n[1]) {
4151 status = SUCCESS;
4152 break;
4153 }
4154 if (num_events_in < clp.n[0])
4155 skip = TRUE;
4156 else if (clp.n[2] > 0 && num_events_in % clp.n[2] != 0)
4157 skip = TRUE;
4158 }
4159 }
4160 }
4161
4162 if (!skip) {
4163 /* find request belonging to this event */
4165 status = SUCCESS;
4166 for (; par->event_name[0]; par++)
4167 if ((par->ar_info.event_id == EVENTID_ALL ||
4168 par->ar_info.event_id == pevent->event_id) &&
4169 (par->ar_info.trigger_mask == TRIGGER_ALL ||
4170 (par->ar_info.trigger_mask & pevent->trigger_mask))
4171 && par->ar_info.enabled) {
4172 /* analyze this event */
4173 status = process_event(par, pevent);
4174 if (status == SUCCESS)
4176 if (status < 0 || status == RPC_SHUTDOWN) /* disk full/stop analyzer */
4177 break;
4178
4179 /* check for Ctrl-C */
4180 status = cm_yield(0);
4181 }
4182 if (status < 0 || status == RPC_SHUTDOWN)
4183 break;
4184 }
4185
4186 /* update ODB statistics once every 100 events */
4187 if (num_events_in % 100 == 0) {
4188 update_stats();
4189 if (!clp.quiet) {
4190 if (out_file)
4191 printf("%s:%d %s:%d events\r", input_file_name, (int) num_events_in,
4193 else
4194 printf("%s:%d events\r", input_file_name, (int) num_events_in);
4195
4196#ifndef OS_WINNT
4197 fflush(stdout);
4198#endif
4199 }
4200 }
4201 } while (1);
4202
4203#ifdef HAVE_PVM
4204 PVM_DEBUG("analyze_run: event loop finished, status = %d", status);
4205#endif
4206
4207 /* signal EOR to slaves */
4208#ifdef HAVE_PVM
4209 if (pvm_master) {
4210 if (status == RPC_SHUTDOWN)
4211 printf("\nShutting down distributed analyzers, please wait...\n");
4213
4214 /* merge slave output files */
4215 if (out_info.filename[0] && !out_append)
4216 status = pvm_merge();
4217
4218 start_time = ss_millitime() - start_time;
4219
4220 update_stats();
4221 if (!clp.quiet) {
4222 if (out_file)
4223 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, num_events_in,
4224 out_info.filename, num_events_out, start_time / 1000.0);
4225 else
4226 printf("%s:%d events, %1.2lfs\n", input_file_name, num_events_in,
4227 start_time / 1000.0);
4228 }
4229 } else if (pvm_slave) {
4230 start_time = ss_millitime() - start_time;
4231
4232 update_stats();
4233 if (!clp.quiet) {
4234 if (out_file)
4235 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, num_events_in,
4236 out_info.filename, num_events_out, start_time / 1000.0);
4237 else
4238 printf("%s:%d events, %1.2lfs\n", input_file_name, num_events_in,
4239 start_time / 1000.0);
4240 }
4241
4242 eor(current_run_number, error);
4243
4244 /* send back tests */
4246
4247 for (i = 0; i < n_test; i++)
4248 pvm_pkbyte((char *) tl[i], sizeof(ANA_TEST), 1);
4249
4250 PVM_DEBUG("analyze_run: send %d tests back to master", n_test);
4251
4253 if (status < 0) {
4254 pvm_perror("pvm_send");
4255 return RPC_SHUTDOWN;
4256 }
4257 } else {
4258 start_time = ss_millitime() - start_time;
4259
4260 update_stats();
4261 if (!clp.quiet) {
4262 if (out_file)
4263 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, num_events_in,
4264 out_info.filename, num_events_out, start_time / 1000.0);
4265 else
4266 printf("%s:%d events, %1.2lfs\n", input_file_name, num_events_in,
4267 start_time / 1000.0);
4268 }
4269
4270 /* call analyzer eor routines */
4271 eor(current_run_number, error);
4272 }
4273#else
4274
4275 start_time = ss_millitime() - start_time;
4276
4277 update_stats();
4278 if (!clp.quiet) {
4279 if (out_file)
4280 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, (int) num_events_in,
4281 out_info.filename, (int) num_events_out, start_time / 1000.0);
4282 else
4283 printf("%s:%d events, %1.2lfs\n", input_file_name, (int) num_events_in,
4284 start_time / 1000.0);
4285 }
4286
4287 /* call analyzer eor routines */
4288 eor(current_run_number, error);
4289
4290#endif
4291
4292 ma_close(file);
4293
4294 free(pevent_unaligned);
4295
4296 return status;
4297}
4298
4299/*------------------------------------------------------------------*/
4300
4302{
4304 char input_file_name[256], output_file_name[256], *prn;
4305 BANK_LIST *bank_list;
4306
4307 if (!clp.quiet)
4308 printf("Running analyzer offline. Stop with \"!\"\n");
4309
4310 run_number = 0;
4311 out_append = ((strchr(clp.input_file_name[0], '%') != NULL) &&
4312 (strchr(clp.output_file_name, '%') == NULL))
4313 || clp.input_file_name[1][0];
4314
4315 /* loop over range of files */
4316 if (clp.run_number[0] > 0) {
4317 if (strchr(clp.input_file_name[0], '%') == NULL) {
4318 printf
4319 ("Input file name must contain a wildcard like \"%%05d\" when using a range.\n");
4320 return 0;
4321 }
4322
4323 if (clp.run_number[0] == 0) {
4324 printf("End of range not specified.\n");
4325 return 0;
4326 }
4327
4328 for (run_number = clp.run_number[0]; run_number <= clp.run_number[1]; run_number++) {
4329 sprintf(input_file_name, clp.input_file_name[0], run_number);
4330 if (strchr(clp.output_file_name, '%') != NULL)
4331 sprintf(output_file_name, clp.output_file_name, run_number);
4332 else
4333 strcpy(output_file_name, clp.output_file_name);
4334
4336 if (status == RPC_SHUTDOWN)
4337 break;
4338 }
4339 } else {
4340 /* loop over input file names */
4341 for (i = 0; clp.input_file_name[i][0] && i < 10; i++) {
4342 strcpy(input_file_name, clp.input_file_name[i]);
4343
4344 /* get run number from input file */
4346 while (strchr(prn, DIR_SEPARATOR) != NULL)
4347 prn = strchr(prn, DIR_SEPARATOR) + 1;
4348
4349 if (strpbrk(prn, "0123456789"))
4350 run_number = atoi(strpbrk(prn, "0123456789"));
4351
4352 if (strchr(clp.output_file_name, '%') != NULL) {
4353 if (run_number == 0) {
4354 printf("Cannot extract run number from input file name.\n");
4355 return 0;
4356 }
4357 sprintf(output_file_name, clp.output_file_name, run_number);
4358 } else
4359 strcpy(output_file_name, clp.output_file_name);
4360
4362 if (status == RPC_SHUTDOWN)
4363 break;
4364 }
4365 }
4366
4367 /* close output file in append mode */
4368 if (out_file && out_append) {
4369 if (out_format == FORMAT_HBOOK) {
4370#ifdef HAVE_HBOOK
4371 char str[80];
4372
4373 HROUT(0, i, bstr);
4374 strcpy(str, "OFFLINE");
4375 HREND(str);
4376#else
4377 cm_msg(MERROR, "loop_runs_offline", "HBOOK support is not compiled in");
4378#endif
4379 } else if (out_format == FORMAT_ROOT) {
4380#ifdef HAVE_ROOT
4382#else
4383 cm_msg(MERROR, "loop_runs_offline", "ROOT support is not compiled in");
4384#endif /* HAVE_ROOT */
4385 } else {
4386 if (out_gzip)
4388 else
4390 }
4391
4392 /* free bank buffer */
4393 for (i = 0; analyze_request[i].event_name[0]; i++) {
4394 bank_list = analyze_request[i].bank_list;
4395
4396 if (bank_list == NULL)
4397 continue;
4398
4399 for (; bank_list->name[0]; bank_list++)
4400 if (bank_list->addr) {
4401 free(bank_list->addr);
4402 bank_list->addr = NULL;
4403 }
4404 }
4405 }
4406#ifdef HAVE_PVM
4407 /* merge slave output files */
4409 pvm_merge();
4410#endif
4411
4412 return CM_SUCCESS;
4413}
4414
4415/*------------------------------------------------------------------*/
4416
4417#ifdef HAVE_PVM
4418
4419int pvm_main(char *argv[])
4420{
4421 int mytid, status, i, j, dtid, *pvm_tid, bufid;
4422 char path[256];
4423 struct timeval timeout;
4424
4425 getcwd(path, 256);
4426
4427 mytid = pvm_mytid();
4428 if (mytid < 0) {
4429 pvm_perror("pvm_mytid");
4430 return 0;
4431 }
4432
4433 chdir(path);
4434
4436 if (status < 0) {
4437 pvm_perror("pvm_setopt");
4438 pvm_exit();
4439 return 0;
4440 }
4441
4443 if (pvm_myparent < 0 && pvm_myparent != PvmNoParent) {
4444 pvm_perror("pvm_parent");
4445 pvm_exit();
4446 return 0;
4447 }
4448
4449 /* check if master */
4450 if (pvm_myparent == PvmNoParent) {
4451 struct pvmhostinfo *hostp;
4452 int n_host, n_arch;
4453
4454#ifdef WIN32
4455 char *p;
4456
4457 /* use no path, executable must be under $PVM_ROOT$/bin/WIN32 */
4458 p = argv[0] + strlen(argv[0]) - 1;
4459 while (p > argv[0] && *p != '\\')
4460 p--;
4461 if (*p == '\\')
4462 p++;
4463 strcpy(path, p);
4464#else
4465 if (strchr(argv[0], '/') == 0) {
4466 getcwd(path, 256);
4467 strcat(path, "/");
4468 strcat(path, argv[0]);
4469 } else
4470 strcpy(path, argv[0]);
4471#endif
4472
4473 /* return if no parallelization selected */
4474 if (clp.n_task == -1)
4475 return SUCCESS;
4476
4477 /* Set number of slaves to start */
4479
4480 pvm_n_task = n_host - 1;
4481 if (clp.n_task != 0)
4482 pvm_n_task = clp.n_task;
4483
4484 if (clp.n_task != 1 && pvm_n_task > n_host - 1)
4485 pvm_n_task = n_host - 1;
4486
4487 if (pvm_n_task == 0)
4488 return SUCCESS;
4489
4490 pvm_master = TRUE;
4491
4492 pvm_tid = malloc(sizeof(int) * pvm_n_task);
4493 pvmc = malloc(sizeof(PVM_CLIENT) * pvm_n_task);
4494
4495 if (pvm_tid == NULL || pvmc == NULL) {
4496 free(pvm_tid);
4497 printf("Not enough memory to allocate PVM structures.\n");
4498 pvm_exit();
4499 return 0;
4500 }
4501
4502 memset(pvmc, 0, sizeof(PVM_CLIENT) * pvm_n_task);
4503
4504 for (i = 0; i < pvm_n_task; i++) {
4505 pvmc[i].buffer = malloc(PVM_BUFFER_SIZE);
4506 if (pvmc[i].buffer == NULL) {
4507 free(pvm_tid);
4508 free(pvmc);
4509 printf("Not enough memory to allocate PVM buffers.\n");
4510 pvm_exit();
4511 return 0;
4512 }
4513 }
4514
4515 /* spawn slaves */
4516 printf("Parallelizing analyzer on %d machines\n", pvm_n_task);
4517 if (pvm_n_task == 1)
4519 else
4520 status =
4522 pvm_tid);
4523 if (status == 0) {
4524 pvm_perror("pvm_spawn");
4525 pvm_exit();
4526 free(pvm_tid);
4527 free(pvmc);
4528 return 0;
4529 }
4530
4531 for (i = 0; i < pvm_n_task; i++) {
4532 pvmc[i].tid = pvm_tid[i];
4533 pvmc[i].wp = 0;
4534 pvmc[i].n_events = 0;
4535 pvmc[i].time = 0;
4537 for (j = 0; j < n_host; j++)
4538 if (dtid == hostp[j].hi_tid)
4539 strcpy(pvmc[i].host, hostp[j].hi_name);
4540 }
4541
4542 PVM_DEBUG("Spawing on hosts:");
4543 for (i = 0; i < pvm_n_task; i++)
4544 PVM_DEBUG("%s", pvmc[i].host);
4545
4546 if (status < pvm_n_task) {
4547 printf("Trouble spawning slaves. Aborting. Error codes are:\n");
4548 for (i = 0; i < pvm_n_task; i++)
4549 printf("TID %d %d\n", i, pvm_tid[i]);
4550
4551 pvm_exit();
4552 free(pvm_tid);
4553 free(pvmc);
4554 return 0;
4555 }
4556
4557 /* send slave index */
4558 for (i = 0; i < pvm_n_task; i++) {
4560
4561 pvm_pkint(&i, 1, 1);
4562
4563 PVM_DEBUG("pvm_main: send index to client %d", i);
4564
4565 status = pvm_send(pvmc[i].tid, TAG_INIT);
4566 if (status < 0) {
4567 pvm_perror("pvm_send");
4568 return 0;
4569 }
4570 }
4571
4572 free(pvm_tid);
4573 } else {
4574 char path[256];
4575
4576 pvm_master = FALSE;
4577 pvm_slave = TRUE;
4578
4579 /* go to path from argv[0] */
4580 strcpy(path, argv[0]);
4581 for (i = strlen(path); i > 0 && path[i] != DIR_SEPARATOR; i--)
4582 path[i] = 0;
4583 if (i > 0)
4584 path[i] = 0;
4585
4586 chdir(path);
4587 PVM_DEBUG("PATH=%s", path);
4588
4589 /* receive slave index */
4590 timeout.tv_sec = 10;
4591 timeout.tv_usec = 0;
4592
4593 bufid = pvm_trecv(-1, -1, &timeout);
4594 if (bufid < 0) {
4595 pvm_perror("pvm_recv");
4596 return 0;
4597 }
4598 if (bufid == 0) {
4599 PVM_DEBUG("pvm_main: timeout receiving index, aborting analyzer.\n");
4600 return 0;
4601 }
4602
4604 if (status < 0) {
4605 pvm_perror("pvm_upkint");
4606 return 0;
4607 }
4608
4609 PVM_DEBUG("Received client ID %d", pvm_client_index);
4610 }
4611
4612 return SUCCESS;
4613}
4614
4615/*------------------------------------------------------------------*/
4616
4617int pvm_send_event(int index, EVENT_HEADER * pevent)
4618{
4619 struct timeval timeout;
4620 int bufid, len, tag, tid, status;
4621
4622 if (pevent->data_size + sizeof(EVENT_HEADER) >= PVM_BUFFER_SIZE) {
4623 printf("Event too large (%d) for PVM buffer (%d), analyzer aborted\n",
4624 pevent->data_size + sizeof(EVENT_HEADER), PVM_BUFFER_SIZE);
4625 return RPC_SHUTDOWN;
4626 }
4627
4628 /* wait on event request */
4629 timeout.tv_sec = 60;
4630 timeout.tv_usec = 0;
4631
4632 bufid = pvm_trecv(pvmc[index].tid, -1, &timeout);
4633 if (bufid < 0) {
4634 pvm_perror("pvm_recv");
4635 return RPC_SHUTDOWN;
4636 }
4637 if (bufid == 0) {
4638 printf("Timeout receiving data requests from %s, aborting analyzer.\n",
4639 pvmc[index].host);
4640 return RPC_SHUTDOWN;
4641 }
4642
4643 status = pvm_bufinfo(bufid, &len, &tag, &tid);
4644 if (status < 0) {
4645 pvm_perror("pvm_bufinfo");
4646 return RPC_SHUTDOWN;
4647 }
4648
4649 PVM_DEBUG("pvm_send_event: received request from client %d", index);
4650
4651 /* send event */
4653
4654 pvm_pkbyte((char *) pevent, pevent->data_size + sizeof(EVENT_HEADER), 1);
4655
4656 PVM_DEBUG("pvm_send_event: send events to client %d", index);
4657
4658 status = pvm_send(tid, TAG_DATA);
4659 if (status < 0) {
4660 pvm_perror("pvm_send");
4661 return RPC_SHUTDOWN;
4662 }
4663
4664 pvmc[index].time = ss_millitime();
4665
4666 return SUCCESS;
4667}
4668
4669/*------------------------------------------------------------------*/
4670
4671int pvm_send_buffer(int index)
4672{
4673 struct timeval timeout;
4674 int i, bufid, len, tag, tid, status;
4675
4676 PVM_DEBUG("pvm_send_buffer: index %d", index);
4677
4678 if (index == -2) {
4679 bufid = pvm_nrecv(-1, -1);
4680 } else {
4681 /* wait on event request with timeout */
4682 timeout.tv_sec = 60;
4683 timeout.tv_usec = 0;
4684
4685 bufid = pvm_trecv(-1, -1, &timeout);
4686 }
4687
4688 if (bufid < 0) {
4689 pvm_perror("pvm_recv");
4690 return RPC_SHUTDOWN;
4691 }
4692 if (bufid == 0) {
4693 if (index == -2)
4694 return SUCCESS;
4695
4696 printf("Timeout receiving data requests, aborting analyzer.\n");
4697 return RPC_SHUTDOWN;
4698 }
4699
4700 status = pvm_bufinfo(bufid, &len, &tag, &tid);
4701 if (status < 0) {
4702 pvm_perror("pvm_bufinfo");
4703 return RPC_SHUTDOWN;
4704 }
4705
4706 /* find index of that client */
4707 for (i = 0; i < pvm_n_task; i++)
4708 if (pvmc[i].tid == tid)
4709 break;
4710
4711 if (i == pvm_n_task) {
4712 cm_msg(MERROR, "pvm_send_buffer", "received message from unknown client %d", tid);
4713 return RPC_SHUTDOWN;
4714 }
4715
4716 PVM_DEBUG("pvm_send_buffer: received request from client %d", i);
4717
4718 /* send event */
4720
4721 pvm_pkbyte((char *) pvmc[i].buffer, pvmc[i].wp, 1);
4722
4723 PVM_DEBUG("pvm_send_buffer: send %d events (%1.1lfkB) to client %d",
4724 pvmc[i].n_events, pvmc[i].wp / 1024.0, i);
4725
4726 status = pvm_send(tid, TAG_DATA);
4727 if (status < 0) {
4728 pvm_perror("pvm_send");
4729 return RPC_SHUTDOWN;
4730 }
4731
4732 pvmc[i].wp = 0;
4733 pvmc[i].n_events = 0;
4734 pvmc[i].time = ss_millitime();
4735
4736 /* if specific client is requested and not emptied, try again */
4737 if (index >= 0 && index != i)
4738 return pvm_send_buffer(index);
4739
4740 return SUCCESS;
4741}
4742
4743/*------------------------------------------------------------------*/
4744
4746{
4747 char str[256];
4748 int i, index, size, status, min, max;
4749
4750 if (par == NULL && pevent->event_id == EVENTID_BOR) {
4751 /* distribute ODB dump */
4752 for (i = 0; i < pvm_n_task; i++) {
4753 status = pvm_send_event(i, pevent);
4754 if (status != SUCCESS)
4755 return status;
4756 }
4757
4758 return SUCCESS;
4759 }
4760
4761 size = sizeof(EVENT_HEADER) + pevent->data_size;
4762
4763 if (par == NULL || (par->ar_info.sampling_type & GET_FARM) == 0) {
4764 /* if not farmed, copy to all client buffers */
4765 for (i = 0; i < pvm_n_task; i++) {
4766 /* if buffer full, empty it */
4767 if (pvmc[i].wp + size >= clp.pvm_buf_size) {
4769 if (status != SUCCESS)
4770 return status;
4771 }
4772
4773 if (size >= PVM_BUFFER_SIZE) {
4774 printf("Event too large (%d) for PVM buffer (%d), analyzer aborted\n", size,
4776 return RPC_SHUTDOWN;
4777 }
4778
4779 memcpy(pvmc[i].buffer + pvmc[i].wp, pevent, size);
4780 pvmc[i].wp += size;
4781 pvmc[i].n_events++;
4782 }
4783 } else {
4784 /* farmed: look for buffer with lowest level */
4785 min = PVM_BUFFER_SIZE;
4786 index = 0;
4787 for (i = 0; i < pvm_n_task; i++)
4788 if (pvmc[i].wp < min) {
4789 min = pvmc[i].wp;
4790 index = i;
4791 }
4792
4793 /* if buffer full, empty it */
4794 if (pvmc[index].wp + size >= clp.pvm_buf_size) {
4796 if (status != SUCCESS)
4797 return status;
4798 }
4799
4800 if (pvmc[index].wp + size >= PVM_BUFFER_SIZE) {
4801 printf("Event too large (%d) for PVM buffer (%d), analyzer aborted\n", size,
4803 return RPC_SHUTDOWN;
4804 }
4805
4806 /* copy to "index" buffer */
4807 memcpy(pvmc[index].buffer + pvmc[index].wp, pevent, size);
4808 pvmc[index].wp += size;
4809 pvmc[index].n_events++;
4810 }
4811
4812 sprintf(str, "%1.3lf: ", (ss_millitime() - pvm_start_time) / 1000.0);
4813 for (i = 0; i < pvm_n_task; i++)
4814 if (i == index)
4815 sprintf(str + strlen(str), "#%d# ", pvmc[i].wp);
4816 else
4817 sprintf(str + strlen(str), "%d ", pvmc[i].wp);
4818 //PVM_DEBUG(str);
4819
4820 /* find min/max buffer level */
4821 min = PVM_BUFFER_SIZE;
4822 max = 0;
4823 for (i = 0; i < pvm_n_task; i++) {
4824 if (pvmc[i].wp > max)
4825 max = pvmc[i].wp;
4826 if (pvmc[i].wp < min)
4827 min = pvmc[i].wp;
4828 }
4829
4830 /* don't send events if all buffers are less than half full */
4831 if (max < clp.pvm_buf_size / 2)
4832 return SUCCESS;
4833
4834 /* if all buffer are more than half full, wait for next request */
4835 if (min > clp.pvm_buf_size / 2) {
4836 status = pvm_send_buffer(-1);
4837 return status;
4838 }
4839
4840 /* probe new requests */
4841 status = pvm_send_buffer(-2);
4842
4843 return status;
4844}
4845
4846/*------------------------------------------------------------------*/
4847
4848int pvm_eor(int eor_tag)
4849{
4850 struct timeval timeout;
4851 int bufid, len, tag, tid, i, j, status, size;
4853 DWORD count;
4854 char str[256];
4855
4856 printf("\n");
4857
4858 for (i = 0; i < pvm_n_task; i++)
4859 pvmc[i].eor_sent = FALSE;
4860
4861 do {
4862 /* flush remaining buffers */
4863 timeout.tv_sec = 60;
4864 timeout.tv_usec = 0;
4865
4866 bufid = pvm_trecv(-1, -1, &timeout);
4867 if (bufid < 0) {
4868 pvm_perror("pvm_recv");
4869 return RPC_SHUTDOWN;
4870 }
4871 if (bufid == 0) {
4872 printf("Timeout receiving data request, aborting analyzer.\n");
4873 return RPC_SHUTDOWN;
4874 }
4875
4876 status = pvm_bufinfo(bufid, &len, &tag, &tid);
4877 if (status < 0) {
4878 pvm_perror("pvm_bufinfo");
4879 return RPC_SHUTDOWN;
4880 }
4881
4882 /* find index of that client */
4883 for (j = 0; j < pvm_n_task; j++)
4884 if (pvmc[j].tid == tid)
4885 break;
4886
4887 if (j == pvm_n_task) {
4888 cm_msg(MERROR, "pvm_eor", "received message from unknown client %d", tid);
4889 return RPC_SHUTDOWN;
4890 }
4891
4892 PVM_DEBUG("pvm_eor: received request from client %d", j);
4893
4894 /* send remaining buffer if data available */
4895 if (eor_tag == TAG_EOR && pvmc[j].wp > 0) {
4897
4898 pvm_pkbyte((char *) pvmc[j].buffer, pvmc[j].wp, 1);
4899
4900 PVM_DEBUG("pvm_eor: send %d events (%1.1lfkB) to client %d",
4901 pvmc[j].n_events, pvmc[j].wp / 1024.0, j);
4902
4903 status = pvm_send(tid, TAG_DATA);
4904 if (status < 0) {
4905 pvm_perror("pvm_send");
4906 return RPC_SHUTDOWN;
4907 }
4908
4909 pvmc[j].wp = 0;
4910 pvmc[j].n_events = 0;
4911 pvmc[j].time = ss_millitime();
4912 } else {
4913 /* send EOR */
4915
4916 if (eor_tag == TAG_EOR)
4917 PVM_DEBUG("pvm_eor: send EOR to client %d", j);
4918 else
4919 PVM_DEBUG("pvm_eor: send EXIT to client %d", j);
4920
4921 printf("Shutting down %s \r", pvmc[j].host);
4922 fflush(stdout);
4923
4924 status = pvm_send(tid, eor_tag);
4925 if (status < 0) {
4926 pvm_perror("pvm_send");
4927 return RPC_SHUTDOWN;
4928 }
4929
4930 pvmc[j].eor_sent = TRUE;
4931
4932 /* wait for EOR reply */
4933 timeout.tv_sec = 60;
4934 timeout.tv_usec = 0;
4935
4936 bufid = pvm_trecv(tid, -1, &timeout);
4937 if (bufid < 0) {
4938 pvm_perror("pvm_recv");
4939 return RPC_SHUTDOWN;
4940 }
4941 if (bufid == 0) {
4942 printf("Timeout receiving EOR request, aborting analyzer.\n");
4943 return RPC_SHUTDOWN;
4944 }
4945
4946 status = pvm_bufinfo(bufid, &len, &tag, &tid);
4947 if (status < 0) {
4948 pvm_perror("pvm_bufinfo");
4949 return RPC_SHUTDOWN;
4950 }
4951
4952 PVM_DEBUG("\nGot %d bytes", len);
4953
4954 tst_buf = malloc(len);
4955 pvm_upkbyte((char *) tst_buf, len, 1);
4956
4957 /* write tests to ODB */
4958 for (i = 0; i < (int) (len / sizeof(ANA_TEST)); i++) {
4959 sprintf(str, "/%s/Tests/%s", analyzer_name, tst_buf[i].name);
4960 count = 0;
4961 size = sizeof(DWORD);
4962 db_get_value(hDB, 0, str, &count, &size, TID_DWORD, TRUE);
4963 count += tst_buf[i].count;
4964
4965 db_set_value(hDB, 0, str, &count, sizeof(DWORD), 1, TID_DWORD);
4966 }
4967
4968 free(tst_buf);
4969 }
4970
4971 /* check if EOR sent to all clients */
4972 for (j = 0; j < pvm_n_task; j++)
4973 if (!pvmc[j].eor_sent)
4974 break;
4975
4976 } while (j < pvm_n_task);
4977
4978 printf("\n");
4979
4980 return SUCCESS;
4981}
4982
4983/*------------------------------------------------------------------*/
4984
4985int pvm_merge()
4986{
4987 int i, j;
4988 char fn[10][8], str[256], file_name[256], error[256];
4989 char ext[10], *p;
4990
4991 strcpy(str, out_info.filename);
4992 if (strchr(str, '%') != NULL)
4994 else
4995 strcpy(file_name, str);
4996
4997 /* check output file extension */
4998 out_gzip = FALSE;
4999 ext[0] = 0;
5000 if (strchr(file_name, '.')) {
5001 p = file_name + strlen(file_name) - 1;
5002 while (*p != '.')
5003 p--;
5004 strcpy(ext, p);
5005 }
5006 if (strncmp(ext, ".gz", 3) == 0) {
5007 out_gzip = TRUE;
5008 *p = 0;
5009 p--;
5010 while (*p != '.' && p > file_name)
5011 p--;
5012 strcpy(ext, p);
5013 }
5014
5015 if (strncmp(ext, ".asc", 4) == 0)
5017 else if (strncmp(ext, ".mid", 4) == 0)
5019 else if (strncmp(ext, ".rz", 3) == 0)
5021 else {
5022 strcpy(error,
5023 "Unknown output data format. Please use file extension .asc, .mid or .rz.\n");
5024 cm_msg(MERROR, "pvm_merge", error);
5025 return 0;
5026 }
5027
5028 if (out_format == FORMAT_HBOOK) {
5029 if (pvm_n_task <= 10) {
5030 for (i = 0; i < pvm_n_task; i++)
5031 sprintf(fn[i], "n%d.rz", i);
5032
5034 } else {
5035 for (i = 0; i <= pvm_n_task / 10; i++) {
5036 for (j = 0; j < 10 && j + i * 10 < pvm_n_task; j++)
5037 sprintf(fn[j], "n%d.rz", j + i * 10);
5038
5039 sprintf(str, "t%d.rz", i);
5040 printf("Merging %d files to %s:\n", j, str);
5041 HMERGE(j, fn, str);
5042 }
5043 for (i = 0; i <= pvm_n_task / 10; i++)
5044 sprintf(fn[i], "t%d.rz", i);
5045
5046 printf("Merging %d files to %s:\n", i, file_name);
5047 HMERGE(i, fn, file_name);
5048 }
5049 }
5050
5051 return SUCCESS;
5052}
5053
5054#endif /* PVM */
5055
5056/*------------------------------------------------------------------*/
5057
5058#ifdef HAVE_ROOT
5059
5060/*==== ROOT socket histo server ====================================*/
5061
5062#if defined ( OS_UNIX )
5063#define THREADRETURN
5064#define THREADTYPE void
5065#endif
5066#if defined( OS_WINNT )
5067#define THREADRETURN 0
5068#define THREADTYPE DWORD WINAPI
5069#endif
5070
5071/*------------------------------------------------------------------*/
5072
5074{
5075 //read pointer to current folder
5076 TMessage *m = 0;
5077 fSocket->Recv(m);
5078 POINTER_T p;
5079 *m >> p;
5080 return (TFolder *) p;
5081}
5082
5083/*------------------------------------------------------------------*/
5084
5086/*
5087 Serve histograms over TCP/IP socket link
5088*/
5089{
5090 char request[256];
5091
5092 TSocket *sock = (TSocket *) arg;
5093
5094 do {
5095
5096 /* close connection if client has disconnected */
5097 if (sock->Recv(request, sizeof(request)) <= 0) {
5098 // printf("Closed connection to %s\n", sock->GetInetAddress().GetHostName());
5099 sock->Close();
5100 delete sock;
5101 return THREADRETURN;
5102
5103 } else {
5104
5106
5107 if (strcmp(request, "GetListOfFolders") == 0) {
5108
5110 if (folder == NULL) {
5111 message->Reset(kMESS_OBJECT);
5112 message->WriteObject(NULL);
5113 sock->Send(*message);
5114 delete message;
5115 continue;
5116 }
5117 //get folder names
5118 TObject *obj;
5119 TObjArray *names = new TObjArray(100);
5120
5121 TCollection *folders = folder->GetListOfFolders();
5122 TIterator *iterFolders = folders->MakeIterator();
5123 while ((obj = iterFolders->Next()) != NULL)
5124 names->Add(new TObjString(obj->GetName()));
5125
5126 //write folder names
5127 message->Reset(kMESS_OBJECT);
5128 message->WriteObject(names);
5129 sock->Send(*message);
5130
5131 for (int i = 0; i < names->GetLast() + 1; i++)
5132 delete(TObjString *) names->At(i);
5133
5134 delete names;
5135
5136 delete message;
5137
5138 } else if (strncmp(request, "FindObject", 10) == 0) {
5139
5141
5142 //get object
5143 TObject *obj;
5144 if (strncmp(request + 10, "Any", 3) == 0)
5145 obj = folder->FindObjectAny(request + 14);
5146 else
5147 obj = folder->FindObject(request + 11);
5148
5149 //write object
5150 if (!obj)
5151 sock->Send("Error");
5152 else {
5153 message->Reset(kMESS_OBJECT);
5154 message->WriteObject(obj);
5155 sock->Send(*message);
5156 }
5157 delete message;
5158
5159 } else if (strncmp(request, "FindFullPathName", 16) == 0) {
5160
5162
5163 //find path
5164 const char *path = folder->FindFullPathName(request + 17);
5165
5166 //write path
5167 if (!path) {
5168 sock->Send("Error");
5169 } else {
5170 TObjString *obj = new TObjString(path);
5171 message->Reset(kMESS_OBJECT);
5172 message->WriteObject(obj);
5173 sock->Send(*message);
5174 delete obj;
5175 }
5176 delete message;
5177
5178 } else if (strncmp(request, "Occurence", 9) == 0) {
5179
5181
5182 //read object
5183 TMessage *m = 0;
5184 sock->Recv(m);
5185 TObject *obj = ((TObject *) m->ReadObject(m->GetClass()));
5186
5187 //get occurence
5188 Int_t retValue = folder->Occurence(obj);
5189
5190 //write occurence
5191 message->Reset(kMESS_OBJECT);
5192 *message << retValue;
5193 sock->Send(*message);
5194
5195 delete message;
5196
5197 } else if (strncmp(request, "GetPointer", 10) == 0) {
5198
5199 //find object
5200 TObject *obj = gROOT->FindObjectAny(request + 11);
5201
5202 //write pointer
5203 message->Reset(kMESS_ANY);
5204 POINTER_T p = (POINTER_T) obj;
5205 *message << p;
5206 sock->Send(*message);
5207
5208 delete message;
5209
5210 } else if (strncmp(request, "Command", 7) == 0) {
5211 char objName[100], method[100];
5212 sock->Recv(objName, sizeof(objName));
5213 sock->Recv(method, sizeof(method));
5214 TObject *object = gROOT->FindObjectAny(objName);
5215 if (object && object->InheritsFrom(TH1::Class())
5216 && strcmp(method, "Reset") == 0)
5217 static_cast < TH1 * >(object)->Reset();
5218
5219 } else if (strncmp(request, "SetCut", 6) == 0) {
5220
5221 //read new settings for a cut
5222 char name[256];
5223 sock->Recv(name, sizeof(name));
5224 TCutG *cut = (TCutG *) gManaHistosFolder->FindObjectAny(name);
5225
5226 TMessage *m = 0;
5227 sock->Recv(m);
5228 TCutG *newc = ((TCutG *) m->ReadObject(m->GetClass()));
5229
5230 if (cut) {
5231 cm_msg(MINFO, "root server thread", "changing cut %s", newc->GetName());
5232 newc->TAttMarker::Copy(*cut);
5233 newc->TAttFill::Copy(*cut);
5234 newc->TAttLine::Copy(*cut);
5235 newc->TNamed::Copy(*cut);
5236 cut->Set(newc->GetN());
5237 for (int i = 0; i < cut->GetN(); ++i) {
5238 cut->SetPoint(i, newc->GetX()[i], newc->GetY()[i]);
5239 }
5240 } else {
5241 cm_msg(MERROR, "root server thread", "ignoring receipt of unknown cut %s",
5242 newc->GetName());
5243 }
5244 delete newc;
5245
5246 } else
5247 printf("SocketServer: Received unknown command \"%s\"\n", request);
5248 }
5249 } while (1);
5250
5251 return THREADRETURN;
5252}
5253
5254/*------------------------------------------------------------------*/
5255
5257{
5258// Server loop listening for incoming network connections on specified port.
5259// Starts a searver_thread for each connection.
5260 int port;
5261
5262 port = *(int *) arg;
5263
5264 printf("Root server listening on port %d...\n", port);
5265 TServerSocket *lsock = new TServerSocket(port, kTRUE);
5266
5267 do {
5268 TSocket *sock = lsock->Accept();
5269
5270 // printf("Established connection to %s\n", sock->GetInetAddress().GetHostName());
5271
5272#if defined ( OS_LINUX )
5273 TThread *thread = new TThread("Server", root_server_thread, sock);
5274 thread->Run();
5275#endif
5276#if defined( _MSC_VER )
5277 LPDWORD lpThreadId = 0;
5279#endif
5280 } while (1);
5281
5282 return THREADRETURN;
5283}
5284
5285/*------------------------------------------------------------------*/
5286
5287void start_root_socket_server(int port)
5288{
5289 static int pport = port;
5290#if defined ( OS_LINUX )
5291 TThread *thread = new TThread("server_loop", root_socket_server, &pport);
5292 thread->Run();
5293#endif
5294#if defined( _MSC_VER )
5295 LPDWORD lpThreadId = 0;
5297#endif
5298}
5299
5300/*------------------------------------------------------------------*/
5301
5302void *root_event_loop(void *arg)
5303/*
5304 Thread wrapper around main event loop
5305*/
5306{
5307 if (clp.online)
5308 loop_online();
5309 else
5311
5312 gSystem->ExitLoop();
5313
5314 return NULL;
5315}
5316
5317#endif /* HAVE_ROOT */
5318
5319/*------------------------------------------------------------------*/
5320
5321int main(int argc, char *argv[])
5322{
5323 INT status, size;
5324 char str[256];
5325 HNDLE hkey;
5326
5327#ifdef HAVE_PVM
5328 int i;
5329
5330 str[0] = 0;
5331 for (i = 0; i < argc; i++) {
5332 strcat(str, argv[i]);
5333 strcat(str, " ");
5334 }
5335 PVM_DEBUG("Analyzer started: %s", str);
5336#endif
5337
5338#ifdef HAVE_ROOT
5339 int argn = 1;
5340 char *argp = (char *) argv[0];
5341
5342 manaApp = new TRint("ranalyzer", &argn, &argp, NULL, 0, true);
5343
5344 /* default server port */
5345 clp.root_port = 9090;
5346#endif
5347
5348 /* get default from environment */
5349 cm_get_environment(clp.host_name, sizeof(clp.host_name), clp.exp_name,
5350 sizeof(clp.exp_name));
5351
5352#ifdef HAVE_HBOOK
5353 /* set default lrec size */
5354 clp.lrec = HBOOK_LREC;
5355#endif /* HAVE_HBOOK */
5356
5357 /* read in command line parameters into clp structure */
5359 if (status != CM_SUCCESS)
5360 return 1;
5361
5362 /* become a daemon */
5363 if (clp.daemon) {
5364 printf("Becoming a daemon...\n");
5365 clp.quiet = TRUE;
5367 }
5368
5369 /* set default buffer size */
5370 if (clp.pvm_buf_size == 0)
5371 clp.pvm_buf_size = 512 * 1024;
5372 else
5373 clp.pvm_buf_size *= 1024;
5374 if (clp.pvm_buf_size > PVM_BUFFER_SIZE) {
5375 printf("Buffer size cannot be larger than %dkB\n", PVM_BUFFER_SIZE / 1024);
5376 return 1;
5377 }
5378
5379 /* set online mode if no input filename is given */
5380 clp.online = (clp.input_file_name[0][0] == 0);
5381
5382#ifdef HAVE_HBOOK
5383 /* set Ntuple format to RWNT if online */
5384 if (clp.online || equal_ustring(clp.output_file_name, "OFLN"))
5385 clp.rwnt = TRUE;
5386#endif /* HAVE_HBOOK */
5387
5388#ifdef HAVE_PVM
5389 status = pvm_main(argv);
5390 if (status != CM_SUCCESS)
5391 return 1;
5392#endif
5393
5394 /* now connect to server */
5395 if (clp.online) {
5396 if (clp.host_name[0])
5397 printf("Connect to experiment %s on host %s...", clp.exp_name, clp.host_name);
5398 else
5399 printf("Connect to experiment %s...", clp.exp_name);
5400 }
5401
5402 status =
5405
5406 if (status == CM_UNDEF_EXP) {
5407 printf("\nError: Experiment \"%s\" not defined.\n", clp.exp_name);
5408 if (getenv("MIDAS_DIR")) {
5409 printf
5410 ("Note that \"MIDAS_DIR\" is defined, which results in a single experiment\n");
5411 printf
5412 ("called \"Default\". If you want to use the \"exptab\" file, undefine \"MIDAS_DIR\".\n");
5413 }
5414 return 1;
5415 } else if (status != CM_SUCCESS) {
5416 std::string s = cm_get_error(status);
5417 printf("\nError: %s\n", s.c_str());
5418 return 1;
5419 }
5420
5421 if (clp.online)
5422 printf("OK\n");
5423
5424 /* set online/offline mode */
5426
5427 size = sizeof(sys_max_event_size);
5428 status = db_get_value(hDB, 0, "/Experiment/MAX_EVENT_SIZE", &sys_max_event_size, &size, TID_DWORD, TRUE);
5429
5430 db_set_value(hDB, 0, "/Runinfo/Online Mode", &clp.online, sizeof(clp.online), 1, TID_INT);
5431
5432 if (clp.online) {
5433 /* check for duplicate name */
5435 if (status == CM_SUCCESS) {
5437 printf("An analyzer named \"%s\" is already running in this experiment.\n",
5439 printf
5440 ("Please select another analyzer name in analyzer.c or stop other analyzer.\n");
5441 return 1;
5442 }
5443
5444 /* register transitions if started online */
5449 printf("Failed to start local RPC server");
5450 return 1;
5451 }
5452 } else {
5453 if (!pvm_slave) { /* slave could run on same machine... */
5455 if (status == CM_SUCCESS) {
5456 /* kill hanging previous analyzer */
5458
5460 if (status == CM_SUCCESS) {
5461 /* analyzer may only run once if offline */
5463 if (status == CM_SHUTDOWN)
5464 printf("Previous analyzer stopped\n");
5465 }
5466 }
5467 }
5468 }
5469
5470#ifdef HAVE_HBOOK
5471 /* register callback for clearing histos */
5473#endif
5474
5475 /* turn on keepalive messages */
5477
5478 /* decrease watchdog timeout in offline mode */
5479 if (!clp.online)
5481
5482 /* turn off watchdog if in debug mode */
5483 if (clp.debug)
5485
5486 /* initialize module parameters */
5489 return 1;
5490 }
5491
5492 /* create ODB structure for output */
5493 sprintf(str, "/%s/Output", analyzer_name);
5495 db_find_key(hDB, 0, str, &hkey);
5496 assert(hkey);
5497 size = sizeof(out_info);
5499
5500#ifdef HAVE_ROOT
5501 /* create the folder for analyzer histograms */
5503 gROOT->GetRootFolder()->AddFolder("histos", "MIDAS Analyzer Histograms");
5505 gROOT->GetListOfBrowsables()->Add(gManaHistosFolder, "histos");
5506
5507 /* convert .rz names to .root names */
5509 strcpy(out_info.last_histo_filename, "last.root");
5510
5512 strcpy(out_info.histo_dump_filename, "his%05d.root");
5513
5514 db_set_record(hDB, hkey, &out_info, sizeof(out_info), 0);
5515
5516 /* start socket server */
5517 if (clp.root_port)
5518 start_root_socket_server(clp.root_port);
5519
5520#endif /* HAVE_ROOT */
5521
5522#ifdef HAVE_HBOOK
5523 /* convert .root names to .rz names */
5524 if (strstr(out_info.last_histo_filename, ".root"))
5525 strcpy(out_info.last_histo_filename, "last.rz");
5526
5527 if (strstr(out_info.histo_dump_filename, ".root"))
5528 strcpy(out_info.histo_dump_filename, "his%05d.rz");
5529
5530 db_set_record(hDB, hkey, &out_info, sizeof(out_info), 0);
5531#endif
5532
5533#ifdef HAVE_HBOOK
5534 /* create global memory */
5535 if (clp.online) {
5537 printf("\nGLOBAL MEMORY NAME = %s\n", out_info.global_memory_name);
5538 } else {
5539 if (equal_ustring(clp.output_file_name, "OFLN")) {
5540 strcpy(str, "OFLN");
5541 HLIMAP(pawc_size / 4, str);
5542 printf("\nGLOBAL MEMORY NAME = %s\n", "OFLN");
5543 } else
5544 HLIMIT(pawc_size / 4);
5545 }
5546#endif /* HAVE_HBOOK */
5547
5548 /* analyzer init function */
5549 if (mana_init() != CM_SUCCESS) {
5551 return 1;
5552 }
5553
5554 /* load histos from last.xxx */
5555 if (clp.online)
5557
5558 /* reqister event requests */
5560
5561 /* initialize ss_getchar */
5562 if (!clp.quiet && !pvm_slave)
5563 ss_getchar(0);
5564
5565 /*---- start main loop ----*/
5566
5567 if (clp.online)
5568 loop_online();
5569 else
5571
5572 /* reset terminal */
5573 if (!clp.quiet && !pvm_slave)
5575
5576 /* call exit function */
5577 mana_exit();
5578
5579 /* save histos to last.xxx */
5580 if (clp.online)
5582
5583#ifdef HAVE_PVM
5584
5585 PVM_DEBUG("Analyzer stopped");
5586
5587 /* exit PVM */
5588 pvm_exit();
5589
5590 /* if PVM slave, don't write *SHM file back */
5591 if (pvm_slave)
5593
5594#endif
5595
5596 /* disconnect from experiment */
5598
5599#ifdef HAVE_ROOT
5600 if (clp.start_rint)
5601 manaApp->Run(true);
5602 printf("\r \n"); /* overwrite superflous ROOT prompt */
5603#endif
5604
5605 return 0;
5606}
5607
5608#ifdef LINK_TEST
5609int odb_size;
5610const char* analyzer_name;
5613int analyzer_init(void) { return 0; }
5614int analyzer_loop(void) { return 0; }
5615int analyzer_exit(void) { return 0; }
5616int ana_end_of_run(INT run_number, char *error) { return 0; }
5617int ana_begin_of_run(INT run_number, char *error) { return 0; }
5618int ana_resume_run(INT run_number, char *error) { return 0; }
5619int ana_pause_run(INT run_number, char *error) { return 0; }
5620#endif
#define FALSE
Definition cfortran.h:309
static void usage()
INT bk_close(void *event, void *pdata)
Definition midas.cxx:16780
INT bk_iterate32a(const void *event, BANK32A **pbk32a, void *pdata)
Definition midas.cxx:17103
INT bk_swap(void *event, BOOL force)
Definition midas.cxx:17157
BOOL bk_is32a(const void *event)
Definition midas.cxx:16437
BOOL bk_is32(const void *event)
Definition midas.cxx:16415
INT bk_iterate32(const void *event, BANK32 **pbk, void *pdata)
Definition midas.cxx:17067
void bk_init(void *event)
Definition midas.cxx:16406
INT bk_iterate(const void *event, BANK **pbk, void *pdata)
Definition midas.cxx:17046
void bk_init32(void *event)
Definition midas.cxx:16469
void bk_create(void *event, const char *name, WORD type, void **pdata)
Definition midas.cxx:16561
INT bk_size(const void *event)
Definition midas.cxx:16495
INT bm_open_buffer(const char *buffer_name, INT buffer_size, INT *buffer_handle)
Definition midas.cxx:6717
INT bm_delete_request(INT request_id)
Definition midas.cxx:8584
INT bm_poll_event()
Definition midas.cxx:11126
INT bm_request_event(HNDLE buffer_handle, short int event_id, short int trigger_mask, INT sampling_type, HNDLE *request_id, EVENT_HANDLER *func)
Definition midas.cxx:8465
INT bm_set_cache_size(INT buffer_handle, size_t read_size, size_t write_size)
Definition midas.cxx:8140
INT cm_register_transition(INT transition, INT(*func)(INT, char *), INT sequence_number)
Definition midas.cxx:3593
INT cm_shutdown(const char *name, BOOL bUnique)
Definition midas.cxx:7400
INT cm_yield(INT millisec)
Definition midas.cxx:5642
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3011
INT cm_register_function(INT id, INT(*func)(INT, void **))
Definition midas.cxx:5790
INT cm_connect_experiment1(const char *host_name, const char *default_exp_name, const char *client_name, void(*func)(char *), INT odb_size, DWORD watchdog_timeout)
Definition midas.cxx:2297
INT cm_cleanup(const char *client_name, BOOL ignore_timeout)
Definition midas.cxx:7610
INT cm_disconnect_experiment(void)
Definition midas.cxx:2846
INT cm_get_environment(char *host_name, int host_name_size, char *exp_name, int exp_name_size)
Definition midas.cxx:2134
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3283
INT cm_exist(const char *name, BOOL bUnique)
Definition midas.cxx:7520
#define CM_SUCCESS
Definition midas.h:582
#define CM_UNDEF_EXP
Definition midas.h:586
#define CM_SHUTDOWN
Definition midas.h:588
#define DB_SUCCESS
Definition midas.h:631
#define DB_NO_MORE_SUBKEYS
Definition midas.h:646
#define SS_SUCCESS
Definition midas.h:663
#define SS_ABORT
Definition midas.h:677
#define SS_FILE_ERROR
Definition midas.h:669
#define SS_INVALID_FORMAT
Definition midas.h:688
#define RPC_SHUTDOWN
Definition midas.h:707
#define RPC_SUCCESS
Definition midas.h:698
unsigned short int WORD
Definition mcstd.h:49
unsigned char BYTE
Definition mcstd.h:48
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define TR_RESUME
Definition midas.h:408
#define TR_PAUSE
Definition midas.h:407
#define TID_DOUBLE
Definition midas.h:343
#define TID_BOOL
Definition midas.h:340
#define TRIGGER_ALL
Definition midas.h:538
#define TR_START
Definition midas.h:405
#define TID_SHORT
Definition midas.h:334
#define FORMAT_FIXED
Definition midas.h:314
#define EQ_PERIODIC
Definition midas.h:414
#define TID_WORD
Definition midas.h:332
#define MINFO
Definition midas.h:560
#define TID_BYTE
Definition midas.h:327
#define MODE_DELETE
Definition midas.h:372
#define TID_STRUCT
Definition midas.h:348
#define FORMAT_ROOT
Definition midas.h:317
#define TID_LINK
Definition midas.h:350
#define TID_STRING
Definition midas.h:346
#define MODE_WRITE
Definition midas.h:371
#define EVENTID_ALL
Definition midas.h:537
#define MERROR
Definition midas.h:559
#define MODE_READ
Definition midas.h:370
#define FORMAT_MIDAS
Definition midas.h:311
#define TID_INT
Definition midas.h:338
#define TR_STOP
Definition midas.h:406
#define TID_FLOAT
Definition midas.h:341
#define TID_DWORD
Definition midas.h:336
#define EQ_SLOW
Definition midas.h:418
#define VALIGN(adr, align)
Definition midas.h:526
#define MIN(a, b)
Definition midas.h:515
#define ALIGN8(x)
Definition midas.h:522
#define MAX(a, b)
Definition midas.h:509
std::string ss_gethostname()
Definition system.cxx:5706
INT ss_get_struct_align()
Definition system.cxx:1319
BOOL ss_kbhit()
Definition system.cxx:3664
DWORD ss_millitime()
Definition system.cxx:3393
INT ss_getchar(BOOL reset)
Definition system.cxx:7503
INT ss_daemon_init(BOOL keep_stdout)
Definition system.cxx:2001
INT ss_sleep(INT millisec)
Definition system.cxx:3628
std::string cm_get_error(INT code)
Definition midas.cxx:455
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
#define WORD_SWAP(x)
Definition msystem.h:65
#define DWORD_SWAP(x)
Definition msystem.h:74
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:3856
INT db_send_changed_records()
Definition odb.cxx:13777
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5415
INT db_open_record(HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info)
Definition odb.cxx:13291
INT db_paste_xml(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
Definition odb.cxx:8998
std::string strcomb1(const char **list)
Definition odb.cxx:598
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
Definition odb.cxx:11805
INT db_get_record_size(HNDLE hDB, HNDLE hKey, INT align, INT *buf_size)
Definition odb.cxx:11615
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6539
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
Definition odb.cxx:12972
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
Definition odb.cxx:8027
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
INT db_load(HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote)
Definition odb.cxx:8126
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7648
INT db_paste(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
Definition odb.cxx:8487
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7215
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10843
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5261
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
INT db_set_record(HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align)
Definition odb.cxx:12291
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5586
INT db_close_record(HNDLE hDB, HNDLE hKey)
Definition odb.cxx:13473
INT db_sscanf(const char *data_str, void *data, INT *data_size, INT i, DWORD tid)
Definition odb.cxx:11314
bool rpc_is_remote(void)
Definition midas.cxx:12761
const char * rpc_tid_name(INT id)
Definition midas.cxx:11764
#define RPC_ANA_CLEAR_HISTOS
Definition mrpc.h:118
INT rpc_tid_size(INT id)
Definition midas.cxx:11757
#define TID_PCOS3
Definition hardware.h:18
#define TID_LRS1877
Definition hardware.h:17
#define TID_LRS1882
Definition hardware.h:16
#define HFNT(A1)
Definition hbook.h:80
#define HRGET(A1, A2, A3)
Definition hbook.h:151
#define HFN(A1, A2)
Definition hbook.h:79
#define HDELET(A1)
Definition hbook.h:50
#define HEXIST(A2)
Definition hbook.h:171
#define HBNT(A1, A2, A3)
Definition hbook.h:34
#define HFNTB(A1, A2)
Definition hbook.h:81
#define HROPEN(A1, A2, A3, A4, A5, A6)
Definition hbook.h:154
#define HLIMIT(A1)
Definition hbook.h:108
#define HIDALL(A1, A2)
Definition hbook.h:96
#define HBNAME(A1, A2, A3, A4)
Definition hbook.h:33
#define HROUT(A1, A2, A3)
Definition hbook.h:155
#define HRESET(A1, A2)
Definition hbook.h:149
#define HREND(A1)
Definition hbook.h:148
#define HLIMAP(A1, A2)
Definition hbook.h:107
#define HBSET(A1, A2, A3)
Definition hbook.h:43
#define HBOOKN(A1, A2, A3, A4, A5, A6)
Definition hbook.h:36
#define HRPUT(A1, A2, A3)
Definition hbook.h:156
int main()
Definition hwtest.cxx:23
void ** info
Definition fesimdaq.cxx:41
INT channel
HNDLE hKey
char flag_char
Definition mana.cxx:266
char config_file_name[10][256]
Definition mana.cxx:249
INT write_event_odb(EVENT_HEADER *pevent)
Definition mana.cxx:2953
void load_last_histos()
Definition mana.cxx:3547
DWORD current_run_number
Definition mana.cxx:210
INT mana_exit()
Definition mana.cxx:1655
char exp_name[NAME_LENGTH]
Definition mana.cxx:243
INT book_ttree(void)
INT mana_init()
Definition mana.cxx:1516
INT pawc_size
#define MA_FORMAT_MIDAS
Definition mana.cxx:3835
INT run_number[2]
Definition mana.cxx:246
void register_requests(void)
Definition mana.cxx:3338
char output_file_name[256]
Definition mana.cxx:245
static int sys_max_event_size
Definition mana.cxx:237
char hbook_types[][8]
Definition mana.cxx:700
DWORD n[4]
Definition mana.cxx:247
INT ana_begin_of_run(INT run_number, char *error)
Definition analyzer.c:101
static struct @2 last_time_event[50]
INT book_ntuples(void)
INT index
Definition mana.cxx:271
INT lock_list[10000]
Definition mana.cxx:219
EVENT_DEF * db_get_event_definition(short int event_id)
Definition mana.cxx:454
BOOL quiet
Definition mana.cxx:256
INT ana_resume_run(INT run_number, char *error)
Definition analyzer.c:122
ANALYZE_REQUEST * _current_par
Definition mana.cxx:3073
INT init_module_parameters(BOOL bclose)
Definition mana.cxx:3693
#define ANALYZER_STATS_STR
Definition mana.cxx:353
void update_request(HNDLE hDB, HNDLE hKey, void *info)
Definition mana.cxx:3308
void test_clear()
Definition mana.cxx:582
INT analyzer_exit(void)
Definition analyzer.c:94
#define MA_DEVICE_DISK
Definition mana.cxx:3830
#define HBOOK_LREC
Definition mana.cxx:230
INT write_event_ascii(FILE *file, EVENT_HEADER *pevent, ANALYZE_REQUEST *par)
Definition mana.cxx:2096
int QUEST[100]
INT out_format
Definition mana.cxx:335
INT lrec
Definition mana.cxx:253
INT tr_stop(INT rn, char *error)
Definition mana.cxx:2036
void test_increment()
Definition mana.cxx:597
INT tr_start(INT rn, char *error)
Definition mana.cxx:2014
DWORD last_time
Definition mana.cxx:3070
const char * analyzer_name
Definition analyzer.c:25
INT loop_runs_offline()
Definition mana.cxx:4301
char param[10][256]
Definition mana.cxx:250
char protect[10][256]
Definition mana.cxx:251
int ma_close(MA_FILE *file)
Definition mana.cxx:3919
void * data
Definition mana.cxx:268
INT odb_size
Definition analyzer.cxx:46
INT write_event_midas(FILE *file, EVENT_HEADER *pevent, ANALYZE_REQUEST *par)
Definition mana.cxx:2321
INT analyzer_init(void)
Definition analyzer.c:87
INT tr_pause(INT rn, char *error)
Definition mana.cxx:2065
INT online
Definition mana.cxx:241
BOOL debug
debug printouts
Definition mana.cxx:254
static struct @1 clp_descrip[]
int ma_read_event(MA_FILE *file, EVENT_HEADER *pevent, int size)
Definition mana.cxx:3932
INT ana_pause_run(INT run_number, char *error)
Definition analyzer.c:115
#define PVM_BUFFER_SIZE
Definition mana.cxx:151
const char * bstr
Definition mana.cxx:188
ANA_TEST ** tl
Definition mana.cxx:543
INT ana_end_of_run(INT run_number, char *error)
Definition analyzer.c:108
INT analyzer_loop_period
Definition analyzer.c:28
INT root_port
Definition mana.cxx:261
BOOL daemon
Definition mana.cxx:258
char input_file_name[10][256]
Definition mana.cxx:244
void test_register(ANA_TEST *t)
Definition mana.cxx:546
INT type
Definition mana.cxx:269
#define ANALYZER_REQUEST_STR
Definition mana.cxx:343
INT pvm_buf_size
Definition mana.cxx:260
void banks_changed(INT hDB, INT hKey, void *info)
Definition mana.cxx:725
static struct @0 clp
BOOL pvm_master
Definition mana.cxx:186
void correct_num_events(INT i)
Definition mana.cxx:3075
INT bor(INT run_number, char *error)
Definition mana.cxx:1675
ANALYZE_REQUEST analyze_request[]
Definition analyzer.c:37
HNDLE hDB
main ODB handle
Definition mana.cxx:207
FILE * out_file
Definition mana.cxx:333
INT analyze_run(INT run_number, char *input_file_name, char *output_file_name)
Definition mana.cxx:4045
BOOL out_append
Definition mana.cxx:336
INT n_task
Definition mana.cxx:259
void odb_load(EVENT_HEADER *pevent)
Definition mana.cxx:3743
BOOL start_rint
Definition mana.cxx:262
char description[1000]
Definition mana.cxx:267
void lock_histo(INT id)
Definition mana.cxx:3523
INT analyzer_loop(void)
Definition analyzer.c:129
INT tr_resume(INT rn, char *error)
Definition mana.cxx:2078
INT getparam(int argc, char **argv)
Definition mana.cxx:361
ANA_OUTPUT_INFO out_info
Definition mana.cxx:49
BOOL ntuple_flag
Definition mana.cxx:216
INT eor(INT run_number, char *error)
Definition mana.cxx:1914
BOOL filter
Definition mana.cxx:248
BOOL verbose
Definition mana.cxx:255
void save_last_histos()
Definition mana.cxx:3597
INT process_event(ANALYZE_REQUEST *par, EVENT_HEADER *pevent)
Definition mana.cxx:3081
INT loop_online()
Definition mana.cxx:3636
MA_FILE * ma_open(char *file_name)
Definition mana.cxx:3852
INT load_parameters(INT run_number)
Definition mana.cxx:633
void receive_event(HNDLE buffer_handle, HNDLE request_id, EVENT_HEADER *pheader, void *pevent)
Definition mana.cxx:3274
BOOL out_gzip
Definition mana.cxx:334
BOOL rwnt
Definition mana.cxx:252
#define MA_DEVICE_PVM
Definition mana.cxx:3833
void update_stats()
Definition mana.cxx:3403
void test_write(int delta_time)
Definition mana.cxx:610
#define STR_INC(p, base)
Definition mana.cxx:2091
char host_name[HOST_NAME_LENGTH]
Definition mana.cxx:242
void add_data_dir(char *result, char *file)
Definition mana.cxx:424
#define MA_FORMAT_YBOS
Definition mana.cxx:3836
BOOL pvm_slave
Definition mana.cxx:186
BOOL no_load
Definition mana.cxx:257
int n_test
Definition mana.cxx:544
short int event_id
Definition mana.cxx:3069
DWORD delta_time
Definition mchart.cxx:37
char addr[128]
Definition mcnaf.cxx:104
char bank_name[4]
Definition mdump.cxx:26
double count
Definition mdump.cxx:33
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
char request[600000]
Definition melog.cxx:90
int * n_events
Definition mfe.cxx:68
DWORD actual_time
Definition mfe.cxx:37
#define DWORD
Definition mhdump.cxx:31
INT bm_get_buffer_level(INT buffer_handle, INT *n_bytes)
Definition midas.cxx:7838
#define DIR_SEPARATOR
Definition midas.h:193
#define ANA_SKIP
Definition midas.h:840
INT HNDLE
Definition midas.h:132
#define CINT(_i)
Definition midas.h:1622
#define HOST_NAME_LENGTH
Definition midas.h:273
DWORD BOOL
Definition midas.h:105
#define DIR_SEPARATOR_STR
Definition midas.h:194
#define DEFAULT_WATCHDOG_TIMEOUT
Definition midas.h:290
void EXPRT close_subfolder(void)
#define ANA_OUTPUT_INFO_STR
Definition midas.h:1325
int INT
Definition midas.h:129
#define DEFAULT_RPC_TIMEOUT
Definition midas.h:287
void EXPRT open_subfolder(const char *name)
#define DEFAULT_MAX_EVENT_SIZE
Definition midas.h:254
#define DEFAULT_BUFFER_SIZE
Definition midas.h:255
#define MAX_ODB_PATH
Definition midas.h:277
#define EVENTID_EOR
Definition midas.h:901
#define TRUE
Definition midas.h:182
#define POINTER_T
Definition midas.h:166
#define EVENTID_BOR
Definition midas.h:900
#define NAME_LENGTH
Definition midas.h:272
#define message(type, str)
#define name(x)
Definition midas_macro.h:24
static char * skip(char **buf, const char *delimiters)
char * type_name[]
Definition mspeaker.cpp:26
INT rn
Definition mstat.cxx:30
INT thread(void *p)
Definition odbedit.cxx:43
INT j
Definition odbhist.cxx:40
double value[100]
Definition odbhist.cxx:42
INT k
Definition odbhist.cxx:40
char str[256]
Definition odbhist.cxx:33
char file_name[256]
Definition odbhist.cxx:41
DWORD status
Definition odbhist.cxx:39
#define PvmRouteDirect
Definition pvm3.h:108
#define PvmNoParent
Definition pvm3.h:201
#define PvmDataInPlace
Definition pvm3.h:68
#define PvmTaskHost
Definition pvm3.h:77
#define PvmHostCompl
Definition pvm3.h:83
#define PvmTaskDefault
Definition pvm3.h:76
#define PvmRoute
Definition pvm3.h:105
#define PvmDataDefault
Definition pvm3.h:66
TObjArray * gHistoFolderStack
TFolder * gManaHistosFolder
TCutG * cut_book(const char *name)
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
char global_memory_name[8]
Definition midas.h:1322
BOOL clear_histos
Definition midas.h:1319
BOOL histo_dump
Definition midas.h:1317
char histo_dump_filename[256]
Definition midas.h:1318
BOOL events_to_odb
Definition midas.h:1321
char filename[256]
Definition midas.h:1315
char last_histo_filename[256]
Definition midas.h:1320
DWORD previous_count
Definition midas.h:1342
DWORD count
Definition midas.h:1341
BOOL registered
Definition midas.h:1340
BOOL value
Definition midas.h:1343
AR_STATS ar_stats
Definition midas.h:1309
HNDLE request_id
Definition midas.h:1298
BANK_LIST * bank_list
Definition midas.h:1292
HNDLE hkey_common
Definition midas.h:1300
void * addr
Definition midas.h:1301
AR_INFO ar_info
Definition midas.h:1289
char event_name[NAME_LENGTH]
Definition midas.h:1288
DWORD events_received
Definition midas.h:1307
DWORD events_written
Definition midas.h:1308
HNDLE buffer_handle
Definition midas.h:1297
BOOL enabled
Definition midas.h:1276
INT sampling_type
Definition midas.h:1274
char client_name[NAME_LENGTH]
Definition midas.h:1277
char buffer[NAME_LENGTH]
Definition midas.h:1275
INT trigger_mask
Definition midas.h:1273
INT event_id
Definition midas.h:1272
char host[NAME_LENGTH]
Definition midas.h:1278
double events_written
Definition midas.h:1284
double events_per_sec
Definition midas.h:1283
double events_received
Definition midas.h:1282
char name[9]
Definition midas.h:1241
void * addr
Definition midas.h:1246
DWORD size
Definition midas.h:1243
HNDLE def_key
Definition midas.h:1248
char ** init_str
Definition midas.h:1244
WORD type
Definition midas.h:1242
DWORD n_data
Definition midas.h:1247
BOOL output_flag
Definition midas.h:1245
Definition midas.h:1215
int type
Definition mana.cxx:448
HNDLE hDefKey
Definition mana.cxx:450
WORD format
Definition mana.cxx:449
short int event_id
Definition mana.cxx:447
BOOL disabled
Definition mana.cxx:451
short int event_id
Definition midas.h:852
DWORD data_size
Definition midas.h:856
DWORD serial_number
Definition midas.h:854
DWORD time_stamp
Definition midas.h:855
short int trigger_mask
Definition midas.h:853
Definition midas.h:1026
INT num_values
Definition midas.h:1028
DWORD type
Definition midas.h:1027
char name[NAME_LENGTH]
Definition midas.h:1029
INT item_size
Definition midas.h:1032
int format
Definition mana.cxx:3841
int rp
Definition mana.cxx:3846
gzFile gzfile
Definition mana.cxx:3844
int fd
Definition mana.cxx:3843
char * buffer
Definition mana.cxx:3845
int device
Definition mana.cxx:3842
char * hi_name
Definition pvm3.h:244
int hi_tid
Definition pvm3.h:243