00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <assert.h>
00014 #include "midas.h"
00015 #include "msystem.h"
00016 #include "hardware.h"
00017
00018 #include "mdsupport.h"
00019
00020 #ifdef HAVE_ZLIB
00021 #include "zlib.h"
00022 #endif
00023
00024
00025
00026
00027 #ifdef OS_WINNT
00028 #define VISUAL_CPLUSPLUS
00029 #endif
00030
00031 #ifdef OS_LINUX
00032 #define f2cFortran
00033 #endif
00034
00035 #ifdef HAVE_HBOOK
00036
00037 #include <cfortran.h>
00038 #include <hbook.h>
00039
00040
00041 #ifndef HFNOV
00042 #define HFNOV(A1,A2) CCALLSFSUB2(HFNOV,hfnov,INT,FLOATV,A1,A2)
00043 #endif
00044
00045 #ifndef HMERGE
00046 #define HMERGE(A1,A2,A3) CCALLSFSUB3(HMERGE,hmerge,INT,STRINGV,STRING,A1,A2,A3)
00047 #endif
00048
00049 #endif
00050
00051 ANA_OUTPUT_INFO out_info;
00052
00053
00054
00055 #ifdef USE_ROOT
00056
00057 #undef abs
00058
00059 #include <assert.h>
00060 #include <TApplication.h>
00061 #include <TKey.h>
00062 #include <TROOT.h>
00063 #include <TH1.h>
00064 #include <TH2.h>
00065 #include <TFile.h>
00066 #include <TTree.h>
00067 #include <TLeaf.h>
00068 #include <TSocket.h>
00069 #include <TServerSocket.h>
00070 #include <TMessage.h>
00071 #include <TObjString.h>
00072 #include <TSystem.h>
00073 #include <TFolder.h>
00074 #include <TRint.h>
00075 #include <TCutG.h>
00076
00077 #ifdef OS_LINUX
00078 #include <TThread.h>
00079 #endif
00080
00081
00082
00083 TApplication *manaApp;
00084 TFolder *gManaHistosFolder = NULL;
00085 TFile *gManaOutputFile = NULL;
00086 TObjArray *gHistoFolderStack = NULL;
00087
00088
00089
00090 typedef struct {
00091 int event_id;
00092 TTree *tree;
00093 int n_branch;
00094 char *branch_name;
00095 int *branch_filled;
00096 int *branch_len;
00097 TBranch **branch;
00098 } EVENT_TREE;
00099
00100 typedef struct {
00101 TFile *f;
00102 int n_tree;
00103 EVENT_TREE *event_tree;
00104 } TREE_STRUCT;
00105
00106 TREE_STRUCT tree_struct;
00107
00108 #endif
00109
00110
00111
00112
00113
00114 #ifdef HAVE_PVM
00115
00116 INT pvm_start_time = 0;
00117
00118 extern BOOL disable_shm_write;
00119
00120 void pvm_debug(char *format, ...)
00121 {
00122 va_list argptr;
00123 char msg[256], str[256];
00124
00125 if (pvm_start_time == 0)
00126 pvm_start_time = ss_millitime();
00127
00128 va_start(argptr, format);
00129 vsprintf(msg, (char *) format, argptr);
00130 va_end(argptr);
00131 sprintf(str, "%1.3lf: %s", (ss_millitime() - pvm_start_time) / 1000.0, msg);
00132 puts(str);
00133 #ifdef OS_LINUX
00134 {
00135 char cmd[256];
00136
00137 sprintf(cmd, "echo > /dev/console \"%s\"", str);
00138 system(cmd);
00139 }
00140 #endif
00141 }
00142
00143 #undef STRICT
00144 #include <pvm3.h>
00145 #endif
00146
00147
00148
00149
00150 #define PVM_BUFFER_SIZE (1024*1024)
00151
00152 #ifdef HAVE_PVM
00153 #define TAG_DATA 1
00154 #define TAG_BOR 2
00155 #define TAG_EOR 3
00156 #define TAG_EXIT 4
00157 #define TAG_INIT 5
00158
00159 int pvm_n_task;
00160 int pvm_myparent;
00161 int pvm_client_index;
00162
00163 typedef struct {
00164 int tid;
00165 char host[80];
00166 char *buffer;
00167 int wp;
00168 DWORD n_events;
00169 DWORD time;
00170 BOOL eor_sent;
00171 } PVM_CLIENT;
00172
00173 PVM_CLIENT *pvmc;
00174
00175 int pvm_eor(int);
00176 int pvm_merge(void);
00177 void pvm_debug(char *format, ...);
00178 int pvm_distribute(ANALYZE_REQUEST * par, EVENT_HEADER * pevent);
00179
00180
00181 #define PVM_DEBUG
00182
00183 #endif
00184
00185 BOOL pvm_master = FALSE, pvm_slave = FALSE;
00186
00187 char *bstr = " ";
00188
00189
00190
00191
00192 extern char *analyzer_name;
00193 extern INT analyzer_loop_period;
00194 extern INT analyzer_init(void);
00195 extern INT analyzer_exit(void);
00196 extern INT analyzer_loop(void);
00197 extern INT ana_begin_of_run(INT run_number, char *error);
00198 extern INT ana_end_of_run(INT run_number, char *error);
00199 extern INT ana_pause_run(INT run_number, char *error);
00200 extern INT ana_resume_run(INT run_number, char *error);
00201 extern INT odb_size;
00202
00203
00204
00205
00206 HNDLE hDB;
00207
00208
00209 DWORD current_run_number;
00210
00211
00212 extern ANALYZE_REQUEST analyze_request[];
00213
00214
00215 BOOL ntuple_flag;
00216
00217
00218 INT lock_list[10000];
00219
00220 #ifdef extname
00221 int quest_[100];
00222 #else
00223 extern int QUEST[100];
00224 #endif
00225
00226 extern INT pawc_size;
00227
00228
00229 #define HBOOK_LREC 8190
00230
00231
00232 #ifndef EXT_EVENT_SIZE
00233 #define EXT_EVENT_SIZE (2*(MAX_EVENT_SIZE+sizeof(EVENT_HEADER)))
00234 #endif
00235
00236
00237 static struct {
00238 INT online;
00239 char host_name[HOST_NAME_LENGTH];
00240 char exp_name[NAME_LENGTH];
00241 char input_file_name[10][256];
00242 char output_file_name[256];
00243 INT run_number[2];
00244 DWORD n[4];
00245 BOOL filter;
00246 char config_file_name[10][256];
00247 char param[10][256];
00248 char protect[10][256];
00249 BOOL rwnt;
00250 INT lrec;
00251 BOOL debug;
00252 BOOL verbose;
00253 BOOL quiet;
00254 BOOL no_load;
00255 BOOL daemon;
00256 INT n_task;
00257 INT pvm_buf_size;
00258 INT root_port;
00259 BOOL start_rint;
00260 } clp;
00261
00262 static struct {
00263 char flag_char;
00264 char description[1000];
00265 void *data;
00266 INT type;
00267 INT n;
00268 INT index;
00269 } clp_descrip[] = {
00270
00271 {
00272 'c', "<filename1> Configuration file name(s). May contain a '%05d' to be\n\
00273 <filename2> replaced by the run number. Up to ten files can be\n\
00274 ... specified in one \"-c\" statement", clp.config_file_name, TID_STRING, 10}, {
00275 'd', " Debug flag when started the analyzer fron a debugger.\n\
00276 Prevents the system to kill the analyzer when the\n\
00277 debugger stops at a breakpoint", &clp.debug, TID_BOOL, 0}, {
00278 'D', " Start analyzer as a daemon in the background (UNIX only).",
00279 &clp.daemon, TID_BOOL, 0}, {
00280 'e', "<experiment> MIDAS experiment to connect to", clp.exp_name, TID_STRING, 1}, {
00281 'f', " Filter mode. Write original events to output file\n\
00282 only if analyzer accepts them (doesn't return ANA_SKIP).\n", &clp.filter, TID_BOOL, 0}, {
00283 'h', "<hostname> MIDAS host to connect to when running the analyzer online",
00284 clp.host_name, TID_STRING, 1}, {
00285 'i', "<filename1> Input file name. May contain a '%05d' to be replaced by\n\
00286 <filename2> the run number. Up to ten input files can be specified\n\
00287 ... in one \"-i\" statement", clp.input_file_name, TID_STRING, 10}, {
00288 'l', " If set, don't load histos from last histo file when\n\
00289 running online.", &clp.no_load, TID_BOOL, 0}, {
00290 'L', " HBOOK LREC size. Default is 8190.", &clp.lrec, TID_INT, 0}, {
00291 'n', "<count> Analyze only \"count\" events.\n\
00292 <first> <last>\n\
00293 Analyze only events from \"first\" to \"last\".\n\
00294 <first> <last> <n>\n\
00295 Analyze every n-th event from \"first\" to \"last\".", clp.n, TID_INT, 4}, {
00296 'o', "<filename> Output file name. Extension may be .mid (MIDAS binary),\n\
00297 .asc (ASCII) or .rz (HBOOK). If the name contains a '%05d',\n\
00298 one output file is generated for each run. Use \"OFLN\" as\n\
00299 output file name to creaate a HBOOK shared memory instead\n\
00300 of a file.", clp.output_file_name, TID_STRING, 1}, {
00301 'p', "<param=value> Set individual parameters to a specific value.\n\
00302 Overrides any setting in configuration files", clp.param, TID_STRING, 10}, {
00303 'P', "<ODB tree> Protect an ODB subtree from being overwritten\n\
00304 with the online data when ODB gets loaded from .mid file", clp.protect, TID_STRING, 10}, {
00305 'q', " Quiet flag. If set, don't display run progress in\n\
00306 offline mode.", &clp.quiet, TID_BOOL, 0}, {
00307 'r', "<range> Range of run numbers to analyzer like \"-r 120 125\"\n\
00308 to analyze runs 120 to 125 (inclusive). The \"-r\"\n\
00309 flag must be used with a '%05d' in the input file name.", clp.run_number, TID_INT, 2},
00310 #ifdef HAVE_PVM
00311 {
00312 't', "<n> Parallelize analyzer using <n> tasks with PVM.", &clp.n_task,
00313 TID_INT, 1}, {
00314 'b', "<n> Buffer size for parallelization in kB.", &clp.pvm_buf_size,
00315 TID_INT, 1},
00316 #endif
00317 #ifdef USE_ROOT
00318 {
00319 's', "<port> Start ROOT histo server under <port>. If port==0, don't start server.", &clp.root_port, TID_INT, 1}, {
00320 'R', " Start ROOT interpreter after analysis has finished.",
00321 &clp.start_rint, TID_BOOL, 0},
00322 #endif
00323 {
00324 'v', " Verbose output.", &clp.verbose, TID_BOOL, 0}, {
00325 'w', " Produce row-wise N-tuples in outpur .rz file. By\n\
00326 default, column-wise N-tuples are used.", &clp.rwnt, TID_BOOL, 0}, {
00327 0}
00328 };
00329
00330 FILE *out_file;
00331 #ifdef HAVE_ZLIB
00332 BOOL out_gzip;
00333 #endif
00334 INT out_format;
00335 BOOL out_append;
00336
00337 void update_stats();
00338 void odb_load(EVENT_HEADER * pevent);
00339
00340
00341
00342 #define ANALYZER_REQUEST_STR "\
00343 Event ID = INT : 0\n\
00344 Trigger mask = INT : -1\n\
00345 Sampling type = INT : 1\n\
00346 Buffer = STRING : [32] SYSTEM\n\
00347 Enabled = BOOL : 1\n\
00348 Client name = STRING : [32] \n\
00349 Host = STRING : [32] \n\
00350 "
00351
00352 #define ANALYZER_STATS_STR "\
00353 Events received = DOUBLE : 0\n\
00354 Events per sec. = DOUBLE : 0\n\
00355 Events written = DOUBLE : 0\n\
00356 "
00357
00358
00359
00360 INT getparam(int argc, char **argv)
00361 {
00362 INT index, i, j, size;
00363
00364
00365 for (index = 1; index < argc;) {
00366
00367 if (argv[index][0] == '-') {
00368 for (j = 0; clp_descrip[j].flag_char; j++)
00369 if (argv[index][1] == clp_descrip[j].flag_char)
00370 break;
00371
00372 if (!clp_descrip[j].flag_char)
00373 goto usage;
00374
00375 if (clp_descrip[j].n > 0 && index >= argc - 1)
00376 goto usage;
00377 index++;
00378
00379 if (clp_descrip[j].type == TID_BOOL) {
00380 *((BOOL *) clp_descrip[j].data) = TRUE;
00381 continue;
00382 }
00383
00384 do {
00385 if (clp_descrip[j].type == TID_STRING)
00386 strcpy((char *) clp_descrip[j].data + clp_descrip[j].index * 256,
00387 argv[index]);
00388 else
00389 db_sscanf(argv[index], clp_descrip[j].data, &size, clp_descrip[j].index,
00390 clp_descrip[j].type);
00391
00392 if (clp_descrip[j].n > 1)
00393 clp_descrip[j].index++;
00394
00395 if (clp_descrip[j].index > clp_descrip[j].n) {
00396 printf("Note more than %d options possible for flag -%c\n",
00397 clp_descrip[j].n, clp_descrip[j].flag_char);
00398 return 0;
00399 }
00400
00401 index++;
00402
00403 } while (index < argc && argv[index][0] != '-');
00404
00405 } else
00406 goto usage;
00407 }
00408
00409 return SUCCESS;
00410
00411 usage:
00412
00413 printf("usage: analyzer [options]\n\n");
00414 printf("valid options are:\n");
00415 for (i = 0; clp_descrip[i].flag_char; i++)
00416 printf(" -%c %s\n", clp_descrip[i].flag_char, clp_descrip[i].description);
00417
00418 return 0;
00419 }
00420
00421
00422
00423 void add_data_dir(char *result, char *file)
00424 {
00425 HNDLE hDB, hkey;
00426 char str[256];
00427 int size;
00428
00429 cm_get_experiment_database(&hDB, NULL);
00430 db_find_key(hDB, 0, "/Logger/Data dir", &hkey);
00431
00432 if (hkey) {
00433 size = sizeof(str);
00434 db_get_data(hDB, hkey, str, &size, TID_STRING);
00435 if (str[strlen(str) - 1] != DIR_SEPARATOR)
00436 strcat(str, DIR_SEPARATOR_STR);
00437 strcat(str, file);
00438 strcpy(result, str);
00439 } else
00440 strcpy(result, file);
00441 }
00442
00443
00444
00445 typedef struct {
00446 short int event_id;
00447 int type;
00448 WORD format;
00449 HNDLE hDefKey;
00450 BOOL disabled;
00451 } EVENT_DEF;
00452
00453 EVENT_DEF *db_get_event_definition(short int event_id)
00454 {
00455 INT i, index, status, size, type;
00456 char str[80];
00457 HNDLE hKey, hKeyRoot;
00458 WORD id;
00459 static EVENT_DEF *event_def = NULL;
00460 static int n_cache = 0;
00461
00462
00463 for (index = 0; index < n_cache; index++)
00464 if (event_def[index].event_id == event_id)
00465 return &event_def[index];
00466
00467
00468
00469 n_cache = index + 1;
00470
00471 event_def = (EVENT_DEF *) realloc(event_def, (n_cache) * sizeof(EVENT_DEF));
00472 assert(event_def);
00473
00474 memset(&event_def[index], 0, sizeof(EVENT_DEF));
00475
00476
00477 if (event_id < 0) {
00478 event_def[index].event_id = event_id;
00479 event_def[index].format = FORMAT_ASCII;
00480 event_def[index].hDefKey = 0;
00481 event_def[index].disabled = FALSE;
00482 return &event_def[index];
00483 }
00484
00485 status = db_find_key(hDB, 0, "/equipment", &hKeyRoot);
00486 if (status != DB_SUCCESS) {
00487 cm_msg(MERROR, "db_get_event_definition", "cannot find /equipment entry in ODB");
00488 return NULL;
00489 }
00490
00491 for (i = 0;; i++) {
00492
00493 status = db_enum_key(hDB, hKeyRoot, i, &hKey);
00494 if (status == DB_NO_MORE_SUBKEYS) {
00495 sprintf(str, "Cannot find event id %d under /equipment", event_id);
00496 cm_msg(MERROR, "db_get_event_definition", str);
00497 return NULL;
00498 }
00499
00500 size = sizeof(id);
00501 status = db_get_value(hDB, hKey, "Common/Event ID", &id, &size, TID_WORD, TRUE);
00502 if (status != DB_SUCCESS)
00503 continue;
00504
00505 size = sizeof(type);
00506 status = db_get_value(hDB, hKey, "Common/Type", &type, &size, TID_INT, TRUE);
00507 if (status != DB_SUCCESS)
00508 continue;
00509
00510 if (id == event_id) {
00511
00512 event_def[index].event_id = id;
00513 event_def[index].type = type;
00514
00515 size = sizeof(str);
00516 str[0] = 0;
00517 db_get_value(hDB, hKey, "Common/Format", str, &size, TID_STRING, TRUE);
00518
00519 if (equal_ustring(str, "Fixed"))
00520 event_def[index].format = FORMAT_FIXED;
00521 else if (equal_ustring(str, "ASCII"))
00522 event_def[index].format = FORMAT_ASCII;
00523 else if (equal_ustring(str, "MIDAS"))
00524 event_def[index].format = FORMAT_MIDAS;
00525 else if (equal_ustring(str, "YBOS"))
00526 event_def[index].format = FORMAT_YBOS;
00527 else if (equal_ustring(str, "DUMP"))
00528 event_def[index].format = FORMAT_DUMP;
00529 else {
00530 cm_msg(MERROR, "db_get_event_definition", "unknown data format");
00531 event_def[index].event_id = 0;
00532 return NULL;
00533 }
00534
00535 db_find_key(hDB, hKey, "Variables", &event_def[index].hDefKey);
00536 return &event_def[index];
00537 }
00538 }
00539 }
00540
00541
00542
00543 ANA_TEST **tl;
00544 int n_test = 0;
00545
00546 void test_register(ANA_TEST * t)
00547 {
00548 int i;
00549
00550
00551 for (i = 0; i < n_test; i++)
00552 if (tl[i] == t)
00553 break;
00554 if (i < n_test) {
00555 t->registered = TRUE;
00556 return;
00557 }
00558
00559
00560 if (n_test == 0) {
00561 tl = (ANA_TEST **) malloc(2 * sizeof(void *));
00562
00563
00564 tl[0] = (ANA_TEST *) malloc(sizeof(ANA_TEST));
00565 strcpy(tl[0]->name, "Always true");
00566 tl[0]->count = 0;
00567 tl[0]->previous_count = 0;
00568 tl[0]->value = TRUE;
00569 tl[0]->registered = TRUE;
00570 n_test++;
00571 } else
00572 tl = (ANA_TEST **) realloc(tl, (n_test + 1) * sizeof(void *));
00573
00574 tl[n_test] = t;
00575 t->count = 0;
00576 t->value = FALSE;
00577 t->registered = TRUE;
00578
00579 n_test++;
00580 }
00581
00582 void test_clear()
00583 {
00584 int i;
00585
00586
00587 for (i = 0; i < n_test; i++) {
00588 tl[i]->count = 0;
00589 tl[i]->value = FALSE;
00590 }
00591
00592
00593 if (n_test > 0)
00594 tl[0]->value = TRUE;
00595 }
00596
00597 void test_increment()
00598 {
00599 int i;
00600
00601
00602 for (i = 0; i < n_test; i++) {
00603 if (tl[i]->value)
00604 tl[i]->count++;
00605 if (i > 0)
00606 tl[i]->value = FALSE;
00607 }
00608 }
00609
00610 void test_write(int delta_time)
00611 {
00612 int i;
00613 char str[256];
00614 float rate;
00615
00616
00617 for (i = 0; i < n_test; i++) {
00618 sprintf(str, "/%s/Tests/%s/Count", analyzer_name, tl[i]->name);
00619 db_set_value(hDB, 0, str, &tl[i]->count, sizeof(DWORD), 1, TID_DWORD);
00620
00621
00622 if (delta_time > 0) {
00623 rate = (float) ((tl[i]->count - tl[i]->previous_count) / (delta_time / 1000.0));
00624 tl[i]->previous_count = tl[i]->count;
00625 sprintf(str, "/%s/Tests/%s/Rate [Hz]", analyzer_name, tl[i]->name);
00626 db_set_value(hDB, 0, str, &rate, sizeof(float), 1, TID_FLOAT);
00627 }
00628 }
00629 }
00630
00631
00632
00633 INT load_parameters(INT run_number)
00634 {
00635 INT i, size, index, status;
00636 HNDLE hkey;
00637 char file_name[256], str[80], value_string[80], param_string[80];
00638 char data[32];
00639 KEY key;
00640
00641
00642 for (i = 0; clp.config_file_name[i][0] && i < 10; i++) {
00643 if (strchr(clp.config_file_name[i], '%') != NULL)
00644 sprintf(file_name, clp.config_file_name[i], run_number);
00645 else
00646 strcpy(file_name, clp.config_file_name[i]);
00647
00648
00649 if (db_load(hDB, 0, file_name, FALSE) == DB_SUCCESS)
00650 printf("Configuration file \"%s\" loaded\n", file_name);
00651 }
00652
00653
00654 for (i = 0; clp.param[i][0] && i < 10; i++) {
00655 if (strchr(clp.param[i], '=') == NULL) {
00656 printf("Error: parameter %s contains no value\n", clp.param[i]);
00657 } else {
00658 strcpy(value_string, strchr(clp.param[i], '=') + 1);
00659 strcpy(param_string, clp.param[i]);
00660 *strchr(param_string, '=') = 0;
00661
00662 index = 0;
00663 if (strchr(param_string, '[') != NULL) {
00664 index = atoi(strchr(param_string, '[') + 1);
00665 *strchr(param_string, '[') = 0;
00666 }
00667
00668 if (param_string[0] == '/')
00669 strcpy(str, param_string);
00670 else
00671 sprintf(str, "/%s/Parameters/%s", analyzer_name, param_string);
00672 db_find_key(hDB, 0, str, &hkey);
00673 if (hkey == 0) {
00674 printf("Error: cannot find parameter %s in ODB\n", str);
00675 } else {
00676 db_get_key(hDB, hkey, &key);
00677 db_sscanf(value_string, data, &size, 0, key.type);
00678
00679 status = db_set_data_index(hDB, hkey, data, size, index, key.type);
00680 if (status == DB_SUCCESS)
00681 printf("Parameter %s changed to %s\n", str, value_string);
00682 else
00683 printf("Cannot change parameter %s\n", str);
00684 }
00685 }
00686 }
00687
00688
00689 cm_yield(0);
00690
00691 return SUCCESS;
00692 }
00693
00694
00695
00696 char hbook_types[][8] = {
00697 "",
00698 ":U:8",
00699 ":I:8",
00700 ":I:8",
00701 ":U:16",
00702 ":I:16",
00703 ":U*4",
00704 ":I*4",
00705 ":I*4",
00706 ":R*4",
00707 ":R*8",
00708 ":U:8",
00709 ":C:32",
00710 "",
00711 "",
00712 "",
00713 "",
00714 "",
00715
00716 };
00717
00718 INT book_ntuples(void);
00719 INT book_ttree(void);
00720
00721 void banks_changed(INT hDB, INT hKey, void *info)
00722 {
00723 char str[80];
00724 HNDLE hkey;
00725
00726
00727 sprintf(str, "/%s/Bank switches", analyzer_name);
00728 db_find_key(hDB, 0, str, &hkey);
00729 db_close_record(hDB, hkey);
00730
00731 #ifdef HAVE_HBOOK
00732 book_ntuples();
00733 printf("N-tuples rebooked\n");
00734 #endif
00735 #ifdef USE_ROOT
00736 book_ttree();
00737 printf("ROOT TTree rebooked\n");
00738 #endif
00739 }
00740
00741 #ifdef HAVE_HBOOK
00742 INT book_ntuples(void)
00743 {
00744 INT index, i, j, status, n_tag, size, id;
00745 HNDLE hkey;
00746 KEY key;
00747 int *t;
00748 char ch_tags[2000];
00749 char rw_tag[512][8];
00750 char str[80], str2[80], key_name[NAME_LENGTH], block_name[NAME_LENGTH];
00751 BANK_LIST *bank_list;
00752 EVENT_DEF *event_def;
00753
00754
00755 ntuple_flag = 1;
00756 size = sizeof(ntuple_flag);
00757 sprintf(str, "/%s/Book N-tuples", analyzer_name);
00758 db_get_value(hDB, 0, str, &ntuple_flag, &size, TID_BOOL, TRUE);
00759
00760 if (!ntuple_flag)
00761 return SUCCESS;
00762
00763
00764 for (i = 0; analyze_request[i].event_name[0]; i++) {
00765 bank_list = analyze_request[i].bank_list;
00766
00767 if (bank_list != NULL)
00768 for (; bank_list->name[0]; bank_list++) {
00769 sprintf(str, "/%s/Bank switches/%s", analyzer_name, bank_list->name);
00770 bank_list->output_flag = FALSE;
00771 size = sizeof(DWORD);
00772 db_get_value(hDB, 0, str, &bank_list->output_flag, &size, TID_DWORD, TRUE);
00773 }
00774 }
00775
00776
00777 sprintf(str, "/%s/Bank switches", analyzer_name);
00778 status = db_find_key(hDB, 0, str, &hkey);
00779 if (status != DB_SUCCESS) {
00780 cm_msg(MERROR, "book_ntuples", "Cannot find key \'%s\', status %d", str, status);
00781 return SUCCESS;
00782 }
00783
00784 db_open_record(hDB, hkey, NULL, 0, MODE_READ, banks_changed, NULL);
00785
00786 if (!clp.rwnt) {
00787
00788
00789
00790 for (index = 0; analyze_request[index].event_name[0]; index++) {
00791
00792 HBNT(analyze_request[index].ar_info.event_id, analyze_request[index].event_name,
00793 bstr);
00794
00795
00796 strcpy(str, "Number");
00797 strcpy(str2, "Run:U*4,Number:U*4,Time:U*4");
00798 t = (int *) (&analyze_request[index].number.run);
00799 HBNAME(analyze_request[index].ar_info.event_id, str, t, str2);
00800
00801 bank_list = analyze_request[index].bank_list;
00802 if (bank_list == NULL) {
00803
00804 event_def =
00805 db_get_event_definition((short int) analyze_request[index].ar_info.
00806 event_id);
00807 if (event_def == NULL) {
00808 cm_msg(MERROR, "book_ntuples", "Cannot find definition of event %s in ODB",
00809 analyze_request[index].event_name);
00810 return 0;
00811 }
00812
00813 ch_tags[0] = 0;
00814 for (i = 0;; i++) {
00815 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
00816 if (status == DB_NO_MORE_SUBKEYS)
00817 break;
00818
00819 db_get_key(hDB, hkey, &key);
00820
00821
00822 strcpy(str, key.name);
00823 for (j = 0; str[j]; j++) {
00824 if (!(str[j] >= 'a' && str[j] <= 'z') &&
00825 !(str[j] >= 'A' && str[j] <= 'Z') && !(str[j] >= '0'
00826 && str[j] <= '9'))
00827 str[j] = '_';
00828 }
00829 strcat(ch_tags, str);
00830 str[0] = 0;
00831
00832 if (key.num_values > 1)
00833 sprintf(str, "(%d)", key.num_values);
00834
00835 if (hbook_types[key.type] != NULL)
00836 strcat(str, hbook_types[key.type]);
00837 else {
00838 cm_msg(MERROR, "book_ntuples",
00839 "Key %s in event %s is of type %s with no HBOOK correspondence",
00840 key.name, analyze_request[index].event_name,
00841 rpc_tid_name(key.type));
00842 return 0;
00843 }
00844 strcat(ch_tags, str);
00845 strcat(ch_tags, ",");
00846 }
00847
00848 ch_tags[strlen(ch_tags) - 1] = 0;
00849 db_get_record_size(hDB, event_def->hDefKey, 0, &size);
00850 analyze_request[index].addr = calloc(1, size);
00851
00852 strcpy(block_name, analyze_request[index].event_name);
00853 block_name[8] = 0;
00854
00855 HBNAME(analyze_request[index].ar_info.event_id, block_name,
00856 analyze_request[index].addr, ch_tags);
00857 } else {
00858
00859 for (; bank_list->name[0]; bank_list++) {
00860 if (bank_list->output_flag == 0)
00861 continue;
00862
00863 if (bank_list->type != TID_STRUCT) {
00864 sprintf(str, "N%s[0,%d]", bank_list->name, bank_list->size);
00865 INT *t = (INT *) & bank_list->n_data;
00866 HBNAME(analyze_request[index].ar_info.event_id,
00867 bank_list->name, t, str);
00868
00869 sprintf(str, "%s(N%s)", bank_list->name, bank_list->name);
00870
00871
00872 if (hbook_types[bank_list->type] != NULL)
00873 strcat(str, hbook_types[bank_list->type]);
00874 else {
00875 cm_msg(MERROR, "book_ntuples",
00876 "Bank %s is of type %s with no HBOOK correspondence",
00877 bank_list->name, rpc_tid_name(bank_list->type));
00878 return 0;
00879 }
00880
00881 if (rpc_tid_size(bank_list->type) == 0) {
00882 cm_msg(MERROR, "book_ntuples",
00883 "Bank %s is of type with unknown size", bank_list->name);
00884 return 0;
00885 }
00886
00887 bank_list->addr =
00888 calloc(bank_list->size, MAX(4, rpc_tid_size(bank_list->type)));
00889
00890 HBNAME(analyze_request[index].ar_info.event_id, bank_list->name,
00891 bank_list->addr, str);
00892 } else {
00893
00894 ch_tags[0] = 0;
00895 for (i = 0;; i++) {
00896 status = db_enum_key(hDB, bank_list->def_key, i, &hkey);
00897 if (status == DB_NO_MORE_SUBKEYS)
00898 break;
00899
00900 db_get_key(hDB, hkey, &key);
00901
00902
00903 strcpy(str, key.name);
00904 for (j = 0; str[j]; j++) {
00905 if (!(str[j] >= 'a' && str[j] <= 'z') &&
00906 !(str[j] >= 'A' && str[j] <= 'Z') && !(str[j] >= '0'
00907 && str[j] <= '9'))
00908 str[j] = '_';
00909 }
00910 strcat(ch_tags, str);
00911 str[0] = 0;
00912
00913 if (key.num_values > 1)
00914 sprintf(str, "(%d)", key.num_values);
00915
00916 if (hbook_types[key.type] != NULL)
00917 strcat(str, hbook_types[key.type]);
00918 else {
00919 cm_msg(MERROR, "book_ntuples",
00920 "Key %s in bank %s is of type %s with no HBOOK correspondence",
00921 key.name, bank_list->name, rpc_tid_name(key.type));
00922 return 0;
00923 }
00924 strcat(ch_tags, str);
00925 strcat(ch_tags, ",");
00926 }
00927
00928 ch_tags[strlen(ch_tags) - 1] = 0;
00929 bank_list->addr = calloc(1, bank_list->size);
00930
00931 HBNAME(analyze_request[index].ar_info.event_id, bank_list->name,
00932 bank_list->addr, ch_tags);
00933 }
00934 }
00935 }
00936
00937
00938 }
00939 } else {
00940
00941
00942
00943 for (index = 0; analyze_request[index].event_name[0]; index++) {
00944
00945 event_def =
00946 db_get_event_definition((short int) analyze_request[index].ar_info.event_id);
00947
00948
00949 if (!event_def)
00950 continue;
00951
00952
00953 if (analyze_request[index].rwnt_buffer_size == 0) {
00954 event_def->disabled = TRUE;
00955 continue;
00956 }
00957
00958 n_tag = 0;
00959
00960 strcpy(rw_tag[n_tag++], "Run");
00961 strcpy(rw_tag[n_tag++], "Number");
00962 strcpy(rw_tag[n_tag++], "Time");
00963
00964 if (clp.verbose) {
00965 printf("NT #%d-1: Run\n", analyze_request[index].ar_info.event_id);
00966 printf("NT #%d-2: Number\n", analyze_request[index].ar_info.event_id);
00967 printf("NT #%d-3: Time\n", analyze_request[index].ar_info.event_id);
00968 }
00969
00970 bank_list = analyze_request[index].bank_list;
00971 if (bank_list == NULL) {
00972
00973
00974 for (i = 0;; i++) {
00975 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
00976 if (status == DB_NO_MORE_SUBKEYS)
00977 break;
00978
00979 db_get_key(hDB, hkey, &key);
00980
00981
00982 strcpy(key_name, key.name);
00983 for (j = 0; key_name[j]; j++) {
00984 if (!(key_name[j] >= 'a' && key_name[j] <= 'z') &&
00985 !(key_name[j] >= 'A' && key_name[j] <= 'Z') &&
00986 !(key_name[j] >= '0' && key_name[j] <= '9'))
00987 key_name[j] = '_';
00988 }
00989
00990 if (key.num_values > 1)
00991 for (j = 0; j < key.num_values; j++) {
00992 sprintf(str, "%s%d", key_name, j);
00993 strncpy(rw_tag[n_tag++], str, 8);
00994
00995 if (clp.verbose)
00996 printf("NT #%d-%d: %s\n", analyze_request[index].ar_info.event_id,
00997 n_tag + 1, str);
00998
00999 if (n_tag >= 512) {
01000 cm_msg(MERROR, "book_ntuples",
01001 "Too much tags for RW N-tupeles (512 maximum)");
01002 return 0;
01003 }
01004 } else {
01005 strncpy(rw_tag[n_tag++], key_name, 8);
01006
01007 if (clp.verbose)
01008 printf("NT #%d-%d: %s\n", analyze_request[index].ar_info.event_id,
01009 n_tag, key_name);
01010 }
01011
01012 if (n_tag >= 512) {
01013 cm_msg(MERROR, "book_ntuples",
01014 "Too much tags for RW N-tupeles (512 maximum)");
01015 return 0;
01016 }
01017 }
01018 } else {
01019
01020 for (; bank_list->name[0]; bank_list++) {
01021
01022 bank_list->n_data = n_tag;
01023
01024 if (bank_list->output_flag == 0)
01025 continue;
01026
01027 if (bank_list->type != TID_STRUCT) {
01028 for (i = 0; i < (INT) bank_list->size; i++) {
01029 sprintf(str, "%s%d", bank_list->name, i);
01030 strncpy(rw_tag[n_tag++], str, 8);
01031
01032 if (clp.verbose)
01033 printf("NT #%d-%d: %s\n", analyze_request[index].ar_info.event_id,
01034 n_tag, str);
01035 if (n_tag >= 512) {
01036 cm_msg(MERROR, "book_ntuples",
01037 "Too much tags for RW N-tupeles (512 maximum)");
01038 return 0;
01039 }
01040 }
01041 } else {
01042
01043 for (i = 0;; i++) {
01044 status = db_enum_key(hDB, bank_list->def_key, i, &hkey);
01045 if (status == DB_NO_MORE_SUBKEYS)
01046 break;
01047
01048 db_get_key(hDB, hkey, &key);
01049
01050
01051 strcpy(key_name, key.name);
01052 for (j = 0; key_name[j]; j++) {
01053 if (!(key_name[j] >= 'a' && key_name[j] <= 'z') &&
01054 !(key_name[j] >= 'A' && key_name[j] <= 'Z') &&
01055 !(key_name[j] >= '0' && key_name[j] <= '9'))
01056 key_name[j] = '_';
01057 }
01058
01059 if (key.num_values > 1)
01060 for (j = 0; j < key.num_values; j++) {
01061 sprintf(str, "%s%d", key_name, j);
01062 strncpy(rw_tag[n_tag++], str, 8);
01063
01064 if (clp.verbose)
01065 printf("NT #%d-%d: %s\n",
01066 analyze_request[index].ar_info.event_id, n_tag, str);
01067
01068 if (n_tag >= 512) {
01069 cm_msg(MERROR, "book_ntuples",
01070 "Too much tags for RW N-tupeles (512 maximum)");
01071 return 0;
01072 }
01073 } else {
01074 strncpy(rw_tag[n_tag++], key_name, 8);
01075 if (clp.verbose)
01076 printf("NT #%d-%d: %s\n",
01077 analyze_request[index].ar_info.event_id, n_tag,
01078 key_name);
01079 }
01080
01081 if (n_tag >= 512) {
01082 cm_msg(MERROR, "book_ntuples",
01083 "Too much tags for RW N-tupeles (512 maximum)");
01084 return 0;
01085 }
01086 }
01087 }
01088 }
01089 }
01090
01091
01092 strcpy(block_name, analyze_request[index].event_name);
01093 block_name[8] = 0;
01094
01095 id = analyze_request[index].ar_info.event_id;
01096 if (HEXIST(id))
01097 HDELET(id);
01098
01099 if (clp.online || equal_ustring(clp.output_file_name, "OFLN"))
01100 HBOOKN(id, block_name, n_tag, bstr,
01101 n_tag * analyze_request[index].rwnt_buffer_size, rw_tag);
01102 else {
01103 strcpy(str, "//OFFLINE");
01104 HBOOKN(id, block_name, n_tag, str, 5120, rw_tag);
01105 }
01106
01107 if (!HEXIST(id)) {
01108 printf("\n");
01109 cm_msg(MINFO, "book_ntuples",
01110 "Cannot book N-tuple #%d. Increase PAWC size via the -s flag or switch off banks",
01111 id);
01112 }
01113 }
01114 }
01115
01116 return SUCCESS;
01117 }
01118 #endif
01119
01120
01121
01122 #ifdef USE_ROOT
01123
01124 char ttree_types[][8] = {
01125 "",
01126 "b",
01127 "B",
01128 "b",
01129 "s",
01130 "S",
01131 "i",
01132 "I",
01133 "I",
01134 "F",
01135 "D",
01136 "b",
01137 "C",
01138 "",
01139 "",
01140 "",
01141 "",
01142 "",
01143
01144 };
01145
01146 INT book_ttree()
01147 {
01148 INT index, i, status, size;
01149 HNDLE hkey;
01150 KEY key;
01151 char leaf_tags[2000];
01152 char str[80];
01153 BANK_LIST *bank_list;
01154 EVENT_DEF *event_def;
01155 EVENT_TREE *et;
01156
01157
01158 ntuple_flag = 1;
01159 size = sizeof(ntuple_flag);
01160 sprintf(str, "/%s/Book TTree", analyzer_name);
01161 db_get_value(hDB, 0, str, &ntuple_flag, &size, TID_BOOL, TRUE);
01162
01163 if (!ntuple_flag)
01164 return SUCCESS;
01165
01166
01167 for (i = 0; analyze_request[i].event_name[0]; i++) {
01168 bank_list = analyze_request[i].bank_list;
01169
01170 if (bank_list != NULL)
01171 for (; bank_list->name[0]; bank_list++) {
01172 sprintf(str, "/%s/Bank switches/%s", analyzer_name, bank_list->name);
01173 bank_list->output_flag = FALSE;
01174 size = sizeof(DWORD);
01175 db_get_value(hDB, 0, str, &bank_list->output_flag, &size, TID_DWORD, TRUE);
01176 }
01177 }
01178
01179
01180 sprintf(str, "/%s/Bank switches", analyzer_name);
01181 status = db_find_key(hDB, 0, str, &hkey);
01182 if (status != DB_SUCCESS) {
01183 cm_msg(MERROR, "book_ttree", "Cannot find key \'%s\', status %d", str, status);
01184 return SUCCESS;
01185 }
01186
01187 db_open_record(hDB, hkey, NULL, 0, MODE_READ, banks_changed, NULL);
01188
01189
01190 for (index = 0; analyze_request[index].event_name[0]; index++) {
01191
01192 tree_struct.n_tree++;
01193 if (tree_struct.n_tree == 1)
01194 tree_struct.event_tree = (EVENT_TREE *) malloc(sizeof(EVENT_TREE));
01195 else
01196 tree_struct.event_tree =
01197 (EVENT_TREE *) realloc(tree_struct.event_tree,
01198 sizeof(EVENT_TREE) * tree_struct.n_tree);
01199
01200 et = tree_struct.event_tree + (tree_struct.n_tree - 1);
01201
01202 et->event_id = analyze_request[index].ar_info.event_id;
01203 et->n_branch = 0;
01204
01205
01206 sprintf(str, "Event \"%s\", ID %d", analyze_request[index].event_name,
01207 et->event_id);
01208 et->tree = new TTree(analyze_request[index].event_name, str);
01209 #if (ROOT_VERSION_CODE >= 262401)
01210 et->tree->SetCircular(analyze_request[index].rwnt_buffer_size);
01211 #endif
01212
01213
01214 et->branch = (TBranch **) malloc(sizeof(TBranch *));
01215 et->branch_name = (char *) malloc(NAME_LENGTH);
01216 et->branch_filled = (int *) malloc(sizeof(int));
01217 et->branch_len = (int *) malloc(sizeof(int));
01218
01219 et->branch[et->n_branch] =
01220 et->tree->Branch("Number", &analyze_request[index].number,
01221 "Run/I:Number/I:Time/i");
01222 strcpy(et->branch_name, "Number");
01223 et->n_branch++;
01224
01225 bank_list = analyze_request[index].bank_list;
01226 if (bank_list == NULL) {
01227
01228 event_def =
01229 db_get_event_definition((short int) analyze_request[index].ar_info.event_id);
01230 if (event_def == NULL) {
01231 cm_msg(MERROR, "book_ttree", "Cannot find definition of event %s in ODB",
01232 analyze_request[index].event_name);
01233 return 0;
01234 }
01235
01236 leaf_tags[0] = 0;
01237 for (i = 0;; i++) {
01238 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
01239 if (status == DB_NO_MORE_SUBKEYS)
01240 break;
01241
01242 db_get_key(hDB, hkey, &key);
01243
01244 strcat(leaf_tags, key.name);
01245
01246 if (key.num_values > 1)
01247 sprintf(leaf_tags + strlen(leaf_tags), "[%d]", key.num_values);
01248
01249 strcat(leaf_tags, "/");
01250
01251 if (ttree_types[key.type] != NULL)
01252 strcat(leaf_tags, ttree_types[key.type]);
01253 else {
01254 cm_msg(MERROR, "book_ttree",
01255 "Key %s in event %s is of type %s with no TTREE correspondence",
01256 key.name, analyze_request[index].event_name,
01257 rpc_tid_name(key.type));
01258 return 0;
01259 }
01260 strcat(leaf_tags, ":");
01261 }
01262
01263 leaf_tags[strlen(leaf_tags) - 1] = 0;
01264
01265 et->branch =
01266 (TBranch **) realloc(et->branch, sizeof(TBranch *) * (et->n_branch + 1));
01267 et->branch_name =
01268 (char *) realloc(et->branch_name, NAME_LENGTH * (et->n_branch + 1));
01269 et->branch_filled =
01270 (int *) realloc(et->branch_filled, sizeof(int) * (et->n_branch + 1));
01271 et->branch_len =
01272 (int *) realloc(et->branch_len, sizeof(int) * (et->n_branch + 1));
01273
01274 et->branch[et->n_branch] =
01275 et->tree->Branch(analyze_request[index].event_name, NULL, leaf_tags);
01276 strcpy(&et->branch_name[et->n_branch * NAME_LENGTH],
01277 analyze_request[index].event_name);
01278 et->n_branch++;
01279 } else {
01280
01281 for (; bank_list->name[0]; bank_list++) {
01282 if (bank_list->output_flag == 0)
01283 continue;
01284
01285 if (bank_list->type != TID_STRUCT) {
01286 sprintf(leaf_tags, "n%s/I:%s[n%s]/", bank_list->name, bank_list->name,
01287 bank_list->name);
01288
01289
01290 if (ttree_types[bank_list->type] != NULL)
01291 strcat(leaf_tags, ttree_types[bank_list->type]);
01292 else {
01293 cm_msg(MERROR, "book_ttree",
01294 "Bank %s is of type %s with no TTREE correspondence",
01295 bank_list->name, rpc_tid_name(bank_list->type));
01296 return 0;
01297 }
01298
01299 if (rpc_tid_size(bank_list->type) == 0) {
01300 cm_msg(MERROR, "book_ttree", "Bank %s is of type with unknown size",
01301 bank_list->name);
01302 return 0;
01303 }
01304
01305 et->branch =
01306 (TBranch **) realloc(et->branch,
01307 sizeof(TBranch *) * (et->n_branch + 1));
01308 et->branch_name =
01309 (char *) realloc(et->branch_name, NAME_LENGTH * (et->n_branch + 1));
01310 et->branch_filled =
01311 (int *) realloc(et->branch_filled, sizeof(int) * (et->n_branch + 1));
01312 et->branch_len =
01313 (int *) realloc(et->branch_len, sizeof(int) * (et->n_branch + 1));
01314
01315 et->branch[et->n_branch] =
01316 et->tree->Branch(bank_list->name, NULL, leaf_tags);
01317 strcpy(&et->branch_name[et->n_branch * NAME_LENGTH], bank_list->name);
01318 et->n_branch++;
01319 } else {
01320
01321 leaf_tags[0] = 0;
01322 for (i = 0;; i++) {
01323 status = db_enum_key(hDB, bank_list->def_key, i, &hkey);
01324 if (status == DB_NO_MORE_SUBKEYS)
01325 break;
01326
01327 db_get_key(hDB, hkey, &key);
01328
01329 strcat(leaf_tags, key.name);
01330
01331 if (key.num_values > 1)
01332 sprintf(leaf_tags + strlen(leaf_tags), "[%d]", key.num_values);
01333
01334 strcat(leaf_tags, "/");
01335
01336 if (ttree_types[key.type] != NULL)
01337 strcat(leaf_tags, ttree_types[key.type]);
01338 else {
01339 cm_msg(MERROR, "book_ttree",
01340 "Key %s in bank %s is of type %s with no HBOOK correspondence",
01341 key.name, bank_list->name, rpc_tid_name(key.type));
01342 return 0;
01343 }
01344 strcat(leaf_tags, ":");
01345 }
01346
01347 leaf_tags[strlen(leaf_tags) - 1] = 0;
01348
01349 et->branch =
01350 (TBranch **) realloc(et->branch,
01351 sizeof(TBranch *) * (et->n_branch + 1));
01352 et->branch_name =
01353 (char *) realloc(et->branch_name, NAME_LENGTH * (et->n_branch + 1));
01354 et->branch_filled =
01355 (int *) realloc(et->branch_filled, sizeof(int) * (et->n_branch + 1));
01356 et->branch_len =
01357 (int *) realloc(et->branch_len, sizeof(int) * (et->n_branch + 1));
01358
01359 et->branch[et->n_branch] =
01360 et->tree->Branch(bank_list->name, NULL, leaf_tags);
01361 strcpy(&et->branch_name[et->n_branch * NAME_LENGTH], bank_list->name);
01362 et->n_branch++;
01363 }
01364 }
01365 }
01366 }
01367
01368 return SUCCESS;
01369 }
01370
01371
01372
01373
01374 INT SaveRootHistograms(TFolder * folder, const char *filename)
01375 {
01376 TDirectory *savedir = gDirectory;
01377 TFile *outf = new TFile(filename, "RECREATE", "Midas Analyzer Histograms");
01378 if (outf == 0) {
01379 cm_msg(MERROR, "SaveRootHistograms", "Cannot create output file %s", filename);
01380 return 0;
01381 }
01382
01383 outf->cd();
01384 folder->Write();
01385 outf->Close();
01386 delete outf;
01387
01388 savedir->cd();
01389 return SUCCESS;
01390 }
01391
01392
01393
01394
01395
01396 void copy_from_last(TFolder * lastFolder, TFolder * onlineFolder)
01397 {
01398
01399 TIter next(lastFolder->GetListOfFolders());
01400 while (TObject * obj = next()) {
01401 const char *name = obj->GetName();
01402
01403 if (obj->InheritsFrom("TFolder")) {
01404
01405 TFolder *onlineSubfolder = (TFolder *) onlineFolder->FindObject(name);
01406 if (onlineSubfolder)
01407 copy_from_last((TFolder *) obj, onlineSubfolder);
01408
01409 } else if (obj->InheritsFrom("TH1")) {
01410
01411
01412
01413 } else if (obj->InheritsFrom("TCutG")) {
01414
01415 TCutG *onlineObj = (TCutG *) onlineFolder->FindObject(name);
01416 if (onlineObj) {
01417 TCutG *lastObj = (TCutG *) obj;
01418
01419 lastObj->TAttMarker::Copy(*onlineObj);
01420 lastObj->TAttFill::Copy(*onlineObj);
01421 lastObj->TAttLine::Copy(*onlineObj);
01422 lastObj->TNamed::Copy(*onlineObj);
01423 onlineObj->Set(lastObj->GetN());
01424 for (int i = 0; i < lastObj->GetN(); ++i) {
01425 onlineObj->SetPoint(i, lastObj->GetX()[i], lastObj->GetY()[i]);
01426 }
01427 }
01428 }
01429 }
01430 return;
01431 }
01432
01433
01434
01435
01436 INT LoadRootHistograms(TFolder * folder, const char *filename)
01437 {
01438 TFile *inf = TFile::Open(filename, "READ");
01439 if (inf == NULL)
01440 printf("Error: File \"%s\" not found\n", filename);
01441 else {
01442
01443 TFolder *lastHistos = (TFolder *) inf->Get("histos");
01444 if (lastHistos) {
01445
01446 copy_from_last(lastHistos, folder);
01447 inf->Close();
01448 }
01449 }
01450 return SUCCESS;
01451 }
01452
01453
01454
01455
01456
01457 INT ClearRootHistograms(TFolder * folder)
01458 {
01459 TIter next(folder->GetListOfFolders());
01460 while (TObject * obj = next())
01461 if (obj->InheritsFrom("TH1"))
01462 ((TH1 *) obj)->Reset();
01463 else if (obj->InheritsFrom("TFolder"))
01464 ClearRootHistograms((TFolder *) obj);
01465 return SUCCESS;
01466 }
01467
01468
01469
01470 INT CloseRootOutputFile()
01471 {
01472 int i;
01473
01474
01475 assert(gManaOutputFile != NULL);
01476
01477
01478 gManaOutputFile->cd();
01479 gManaHistosFolder->Write();
01480
01481
01482 gManaOutputFile->Write();
01483 gManaOutputFile->Close();
01484 delete gManaOutputFile;
01485 gManaOutputFile = NULL;
01486
01487
01488 for (i = 0; i < tree_struct.n_tree; i++)
01489 if (tree_struct.event_tree[i].branch) {
01490 free(tree_struct.event_tree[i].branch);
01491 free(tree_struct.event_tree[i].branch_name);
01492 free(tree_struct.event_tree[i].branch_filled);
01493 free(tree_struct.event_tree[i].branch_len);
01494 tree_struct.event_tree[i].branch = NULL;
01495 }
01496
01497
01498 free(tree_struct.event_tree);
01499 tree_struct.event_tree = NULL;
01500 tree_struct.n_tree = 0;
01501
01502
01503 gROOT->cd();
01504
01505 return SUCCESS;
01506 }
01507
01508 #endif
01509
01510
01511
01512 INT mana_init()
01513 {
01514 ANA_MODULE **module;
01515 INT i, j, status, size;
01516 HNDLE hkey;
01517 char str[256], block_name[32];
01518 BANK_LIST *bank_list;
01519 double dummy;
01520
01521 sprintf(str, "/%s/Output", analyzer_name);
01522 db_find_key(hDB, 0, str, &hkey);
01523
01524 if (clp.online) {
01525 status =
01526 db_open_record(hDB, hkey, &out_info, sizeof(out_info), MODE_READ, NULL, NULL);
01527 if (status != DB_SUCCESS) {
01528 cm_msg(MERROR, "bor", "Cannot read output info record");
01529 return 0;
01530 }
01531 }
01532
01533
01534 for (i = 0; analyze_request[i].event_name[0]; i++) {
01535 bank_list = analyze_request[i].bank_list;
01536
01537 if (bank_list == NULL)
01538 continue;
01539
01540 for (; bank_list->name[0]; bank_list++) {
01541 strncpy(block_name, bank_list->name, 4);
01542 block_name[4] = 0;
01543
01544 if (bank_list->type == TID_STRUCT) {
01545 sprintf(str, "/Equipment/%s/Variables/%s", analyze_request[i].event_name,
01546 block_name);
01547 db_check_record(hDB, 0, str, strcomb((const char **)bank_list->init_str), TRUE);
01548 db_find_key(hDB, 0, str, &hkey);
01549 bank_list->def_key = hkey;
01550 } else {
01551 sprintf(str, "/Equipment/%s/Variables/%s", analyze_request[i].event_name,
01552 block_name);
01553 status = db_find_key(hDB, 0, str, &hkey);
01554 if (status != DB_SUCCESS) {
01555 dummy = 0;
01556 db_set_value(hDB, 0, str, &dummy, rpc_tid_size(bank_list->type), 1,
01557 bank_list->type);
01558 }
01559 bank_list->def_key = hkey;
01560 }
01561 }
01562 }
01563
01564
01565 for (i = 0; analyze_request[i].event_name[0]; i++) {
01566 if (analyze_request[i].init_string) {
01567 sprintf(str, "/Equipment/%s/Variables", analyze_request[i].event_name);
01568 db_check_record(hDB, 0, str, strcomb((const char **)analyze_request[i].init_string), TRUE);
01569 }
01570 }
01571
01572
01573 sprintf(str, "/%s/Tests", analyzer_name);
01574 db_find_key(hDB, 0, str, &hkey);
01575 if (hkey)
01576 db_delete_key(hDB, hkey, FALSE);
01577
01578 #ifdef HAVE_HBOOK
01579
01580 if (clp.online) {
01581
01582 status = book_ntuples();
01583 if (status != SUCCESS)
01584 return status;
01585 } else {
01586 if (equal_ustring(clp.output_file_name, "OFLN")) {
01587
01588 status = book_ntuples();
01589 if (status != SUCCESS)
01590 return status;
01591 }
01592 }
01593 #endif
01594
01595 #ifdef USE_ROOT
01596 if (clp.online) {
01597
01598 status = book_ttree();
01599 if (status != SUCCESS)
01600 return status;
01601 }
01602 #endif
01603
01604
01605 status = analyzer_init();
01606 if (status != SUCCESS)
01607 return status;
01608
01609
01610 for (i = 0; analyze_request[i].event_name[0]; i++) {
01611 module = analyze_request[i].ana_module;
01612 for (j = 0; module != NULL && module[j] != NULL; j++) {
01613
01614
01615 sprintf(str, "/%s/Module switches/%s", analyzer_name, module[j]->name);
01616 module[j]->enabled = TRUE;
01617 size = sizeof(BOOL);
01618 db_get_value(hDB, 0, str, &module[j]->enabled, &size, TID_BOOL, TRUE);
01619
01620 if (module[j]->init != NULL && module[j]->enabled) {
01621
01622 #ifdef USE_ROOT
01623
01624 sprintf(str, "Histos for module %s", module[j]->name);
01625 module[j]->histo_folder = (TFolder *) gROOT->FindObjectAny(module[j]->name);
01626 if (!module[j]->histo_folder)
01627 module[j]->histo_folder =
01628 gManaHistosFolder->AddFolder(module[j]->name, str);
01629 else if (strcmp(((TObject *) module[j]->histo_folder)->ClassName(), "TFolder")
01630 != 0) {
01631 cm_msg(MERROR, "mana_init",
01632 "Fatal error: ROOT Object \"%s\" of class \"%s\" exists but it is not a TFolder, exiting!",
01633 module[j]->name,
01634 ((TObject *) module[j]->histo_folder)->ClassName());
01635 exit(1);
01636 }
01637 gHistoFolderStack->Clear();
01638 gHistoFolderStack->Add((TObject *) module[j]->histo_folder);
01639 #endif
01640
01641 module[j]->init();
01642 }
01643 }
01644 }
01645
01646 return SUCCESS;
01647 }
01648
01649
01650
01651 INT mana_exit()
01652 {
01653 ANA_MODULE **module;
01654 INT i, j;
01655
01656
01657 for (i = 0; analyze_request[i].event_name[0]; i++) {
01658 module = analyze_request[i].ana_module;
01659 for (j = 0; module != NULL && module[j] != NULL; j++)
01660 if (module[j]->exit != NULL && module[j]->enabled) {
01661 module[j]->exit();
01662 }
01663 }
01664
01665
01666 return analyzer_exit();
01667 }
01668
01669
01670
01671 INT bor(INT run_number, char *error)
01672 {
01673 ANA_MODULE **module;
01674 INT i, j, size;
01675 char str[256], file_name[256], *ext_str;
01676 BANK_LIST *bank_list;
01677
01678
01679 load_parameters(run_number);
01680
01681 for (i = 0; analyze_request[i].event_name[0]; i++) {
01682
01683 bank_list = analyze_request[i].bank_list;
01684
01685 if (bank_list != NULL)
01686 for (; bank_list->name[0]; bank_list++) {
01687 sprintf(str, "/%s/Bank switches/%s", analyzer_name, bank_list->name);
01688 bank_list->output_flag = FALSE;
01689 size = sizeof(DWORD);
01690 db_get_value(hDB, 0, str, &bank_list->output_flag, &size, TID_DWORD, TRUE);
01691 }
01692
01693
01694 module = analyze_request[i].ana_module;
01695 for (j = 0; module != NULL && module[j] != NULL; j++) {
01696 sprintf(str, "/%s/Module switches/%s", analyzer_name, module[j]->name);
01697 module[j]->enabled = TRUE;
01698 size = sizeof(BOOL);
01699 db_get_value(hDB, 0, str, &module[j]->enabled, &size, TID_BOOL, TRUE);
01700 }
01701 }
01702
01703
01704 if (clp.online && out_info.clear_histos) {
01705 #ifdef HAVE_HBOOK
01706 int hid[10000];
01707 int n;
01708
01709 for (i = 0; analyze_request[i].event_name[0]; i++)
01710 if (analyze_request[i].bank_list != NULL)
01711 if (HEXIST(analyze_request[i].ar_info.event_id))
01712 HRESET(analyze_request[i].ar_info.event_id, bstr);
01713
01714
01715 HIDALL(hid, n);
01716 for (i = 0; i < n; i++) {
01717 for (j = 0; j < 10000; j++)
01718 if (lock_list[j] == 0 || lock_list[j] == hid[i])
01719 break;
01720
01721
01722 if (lock_list[j] != hid[i])
01723 HRESET(hid[i], bstr);
01724 }
01725 #endif
01726
01727 #ifdef USE_ROOT
01728
01729 if (clp.online && out_info.clear_histos)
01730 ClearRootHistograms(gManaHistosFolder);
01731 #endif
01732
01733
01734 test_clear();
01735 }
01736 #ifdef USE_ROOT
01737 if (clp.online) {
01738
01739 for (i = 0; i < tree_struct.n_tree; i++)
01740 tree_struct.event_tree[i].tree->Reset();
01741 }
01742 #endif
01743
01744
01745 if (!clp.online && out_file == NULL && !pvm_master
01746 && !equal_ustring(clp.output_file_name, "OFLN")) {
01747 if (out_info.filename[0]) {
01748 strcpy(str, out_info.filename);
01749 if (strchr(str, '%') != NULL)
01750 sprintf(file_name, str, run_number);
01751 else
01752 strcpy(file_name, str);
01753
01754
01755 #ifdef HAVE_ZLIB
01756 out_gzip = FALSE;
01757 #endif
01758 if (strchr(file_name, '.')) {
01759 ext_str = file_name + strlen(file_name) - 1;
01760 while (*ext_str != '.')
01761 ext_str--;
01762
01763 if (strncmp(ext_str, ".gz", 3) == 0) {
01764 #ifdef HAVE_ZLIB
01765 out_gzip = TRUE;
01766 ext_str--;
01767 while (*ext_str != '.' && ext_str > file_name)
01768 ext_str--;
01769 #else
01770 strcpy(error,
01771 ".gz extension not possible because zlib support is not compiled in.\n");
01772 cm_msg(MERROR, "bor", error);
01773 return 0;
01774 #endif
01775 }
01776
01777 if (strncmp(ext_str, ".asc", 4) == 0)
01778 out_format = FORMAT_ASCII;
01779 else if (strncmp(ext_str, ".mid", 4) == 0)
01780 out_format = FORMAT_MIDAS;
01781 else if (strncmp(ext_str, ".rz", 3) == 0)
01782 out_format = FORMAT_HBOOK;
01783 else if (strncmp(ext_str, ".root", 5) == 0)
01784 out_format = FORMAT_ROOT;
01785 else {
01786 strcpy(error,
01787 "Unknown output data format. Please use file extension .asc, .mid, .rz or .root.\n");
01788 cm_msg(MERROR, "bor", error);
01789 return 0;
01790 }
01791 } else
01792 out_format = FORMAT_ASCII;
01793
01794 #ifdef HAVE_PVM
01795
01796 if (pvm_slave) {
01797
01798 if (strchr(file_name, '.')) {
01799 strcpy(str, strchr(file_name, '.') + 1);
01800 sprintf(file_name, "n%d", pvm_client_index);
01801 strcat(file_name, ".");
01802 strcat(file_name, str);
01803 } else {
01804 sprintf(file_name, "n%d", pvm_client_index);
01805 }
01806
01807 PVM_DEBUG("BOR: file_name = %s", file_name);
01808 }
01809 #endif
01810
01811
01812 if (out_format == FORMAT_HBOOK) {
01813 #ifdef HAVE_HBOOK
01814 int status, lrec;
01815 char str2[80];
01816
01817 lrec = clp.lrec;
01818 #ifdef extname
01819 quest_[9] = 65000;
01820 #else
01821 QUEST[9] = 65000;
01822 #endif
01823
01824 strcpy(str, "BSIZE");
01825 HBSET(str, HBOOK_LREC, status);
01826 strcpy(str, "OFFLINE");
01827 strcpy(str2, "NQP");
01828 HROPEN(1, str, file_name, str2, lrec, status);
01829 if (status != 0) {
01830 sprintf(error, "Cannot open output file %s", out_info.filename);
01831 cm_msg(MERROR, "bor", error);
01832 out_file = NULL;
01833 return 0;
01834 } else
01835 out_file = (FILE *) 1;
01836 #else
01837 cm_msg(MERROR, "bor", "HBOOK support is not compiled in");
01838 #endif
01839 }
01840
01841 else if (out_format == FORMAT_ROOT) {
01842 #ifdef USE_ROOT
01843
01844 assert(gManaOutputFile == NULL);
01845
01846 gManaOutputFile =
01847 new TFile(file_name, "RECREATE", "Midas Analyzer output file");
01848 if (gManaOutputFile == NULL) {
01849 sprintf(error, "Cannot open output file %s", out_info.filename);
01850 cm_msg(MERROR, "bor", error);
01851 out_file = NULL;
01852 return 0;
01853 }
01854
01855
01856 gManaOutputFile->cd();
01857
01858 out_file = (FILE *) 1;
01859 #else
01860 cm_msg(MERROR, "bor", "ROOT support is not compiled in");
01861 #endif
01862 }
01863
01864 else {
01865 #ifdef HAVE_ZLIB
01866 if (out_gzip)
01867 out_file = (FILE *) gzopen(file_name, "wb");
01868 else
01869 #endif
01870 if (out_format == FORMAT_ASCII)
01871 out_file = fopen(file_name, "wt");
01872 else
01873 out_file = fopen(file_name, "wb");
01874 if (out_file == NULL) {
01875 sprintf(error, "Cannot open output file %s", file_name);
01876 cm_msg(MERROR, "bor", error);
01877 return 0;
01878 }
01879 }
01880 } else
01881 out_file = NULL;
01882
01883 #ifdef HAVE_HBOOK
01884
01885 if (out_format == FORMAT_HBOOK) {
01886 int status = book_ntuples();
01887 if (status != SUCCESS)
01888 return status;
01889 }
01890 #endif
01891
01892 #ifdef USE_ROOT
01893
01894 if (out_format == FORMAT_ROOT) {
01895 int status = book_ttree();
01896 if (status != SUCCESS)
01897 return status;
01898 }
01899 #endif
01900
01901 }
01902
01903
01904
01905 current_run_number = run_number;
01906
01907
01908 for (i = 0; analyze_request[i].event_name[0]; i++) {
01909 module = analyze_request[i].ana_module;
01910 for (j = 0; module != NULL && module[j] != NULL; j++)
01911 if (module[j]->bor != NULL && module[j]->enabled) {
01912 module[j]->bor(run_number);
01913 }
01914 }
01915
01916
01917 return ana_begin_of_run(run_number, error);
01918 }
01919
01920
01921
01922 INT eor(INT run_number, char *error)
01923 {
01924 ANA_MODULE **module;
01925 BANK_LIST *bank_list;
01926 INT i, j, status;
01927 char str[256], file_name[256];
01928
01929
01930 for (i = 0; analyze_request[i].event_name[0]; i++) {
01931 module = analyze_request[i].ana_module;
01932 for (j = 0; module != NULL && module[j] != NULL; j++)
01933 if (module[j]->eor != NULL && module[j]->enabled) {
01934 module[j]->eor(run_number);
01935 }
01936 }
01937
01938
01939 status = ana_end_of_run(run_number, error);
01940
01941
01942 if (out_info.histo_dump && clp.online) {
01943 strcpy(str, out_info.histo_dump_filename);
01944 if (strchr(str, '%') != NULL)
01945 sprintf(file_name, str, run_number);
01946 else
01947 strcpy(file_name, str);
01948
01949 add_data_dir(str, file_name);
01950 #ifdef HAVE_HBOOK
01951 for (i = 0; i < (int) strlen(str); i++)
01952 if (isupper(str[i]))
01953 break;
01954
01955 if (i < (int) strlen(str)) {
01956 printf
01957 ("Error: Due to a limitation in HBOOK, directoy names may not contain uppercase\n");
01958 printf(" characters. Histogram saving to %s will not work.\n", str);
01959 } else {
01960 char str2[256];
01961 strcpy(str2, "NT");
01962 HRPUT(0, str, str2);
01963 }
01964 #endif
01965
01966 #ifdef USE_ROOT
01967 SaveRootHistograms(gManaHistosFolder, str);
01968 #endif
01969 }
01970
01971
01972 if (out_file && !out_append) {
01973 if (out_format == FORMAT_HBOOK) {
01974 #ifdef HAVE_HBOOK
01975 HROUT(0, i, bstr);
01976 strcpy(str, "OFFLINE");
01977 HREND(str);
01978 #else
01979 cm_msg(MERROR, "eor", "HBOOK support is not compiled in");
01980 #endif
01981 } else if (out_format == FORMAT_ROOT) {
01982 #ifdef USE_ROOT
01983 CloseRootOutputFile();
01984 #else
01985 cm_msg(MERROR, "eor", "ROOT support is not compiled in");
01986 #endif
01987 } else {
01988 #ifdef HAVE_ZLIB
01989 if (out_gzip)
01990 gzclose(out_file);
01991 else
01992 #endif
01993 fclose(out_file);
01994 }
01995
01996 out_file = NULL;
01997
01998
01999 for (i = 0; analyze_request[i].event_name[0]; i++) {
02000 bank_list = analyze_request[i].bank_list;
02001
02002 if (bank_list == NULL) {
02003 if (analyze_request[i].addr) {
02004 free(analyze_request[i].addr);
02005 analyze_request[i].addr = NULL;
02006 }
02007 } else {
02008 for (; bank_list->name[0]; bank_list++)
02009 if (bank_list->addr) {
02010 free(bank_list->addr);
02011 bank_list->addr = NULL;
02012 }
02013 }
02014 }
02015 }
02016
02017 return status;
02018 }
02019
02020
02021
02022
02023
02024 INT tr_start(INT rn, char *error)
02025 {
02026 INT status, i;
02027
02028
02029 for (i = 0; analyze_request[i].event_name[0]; i++) {
02030 analyze_request[i].ar_stats.events_received = 0;
02031 analyze_request[i].ar_stats.events_per_sec = 0;
02032 analyze_request[i].ar_stats.events_written = 0;
02033 analyze_request[i].events_received = 0;
02034 analyze_request[i].events_written = 0;
02035 }
02036
02037 status = bor(rn, error);
02038 if (status != SUCCESS)
02039 return status;
02040
02041 return SUCCESS;
02042 }
02043
02044
02045
02046 INT tr_stop(INT rn, char *error)
02047 {
02048 INT i, status, n_bytes;
02049
02050
02051
02052 if (rpc_is_remote())
02053 while (bm_poll_event(TRUE));
02054 else
02055 for (i = 0; analyze_request[i].event_name[0]; i++) {
02056 do {
02057 bm_get_buffer_level(analyze_request[i].buffer_handle, &n_bytes);
02058 if (n_bytes > 0)
02059 cm_yield(100);
02060 } while (n_bytes > 0);
02061 }
02062
02063
02064 update_stats();
02065
02066 status = eor(rn, error);
02067 if (status != SUCCESS)
02068 return status;
02069
02070 return CM_SUCCESS;
02071 }
02072
02073
02074
02075 INT tr_pause(INT rn, char *error)
02076 {
02077 INT status;
02078
02079 status = ana_pause_run(rn, error);
02080 if (status != CM_SUCCESS)
02081 return status;
02082
02083 return CM_SUCCESS;
02084 }
02085
02086
02087
02088 INT tr_resume(INT rn, char *error)
02089 {
02090 INT status;
02091
02092 status = ana_resume_run(rn, error);
02093 if (status != CM_SUCCESS)
02094 return status;
02095
02096 return CM_SUCCESS;
02097 }
02098
02099
02100
02101 #define STR_INC(p,base) { p+=strlen(p); \
02102 if (p > base+sizeof(base)) \
02103 cm_msg(MERROR, "STR_INC", "ASCII buffer too small"); }
02104
02105
02106 INT write_event_ascii(FILE * file, EVENT_HEADER * pevent, ANALYZE_REQUEST * par)
02107 {
02108 INT status, size, i, j, count;
02109 BOOL exclude;
02110 BANK_HEADER *pbh;
02111 BANK_LIST *pbl;
02112 EVENT_DEF *event_def;
02113 BANK *pbk;
02114 BANK32 *pbk32;
02115 void *pdata;
02116 char *pbuf, name[5], type_name[10];
02117 LRS1882_DATA *lrs1882;
02118 LRS1877_DATA *lrs1877;
02119 LRS1877_HEADER *lrs1877_header;
02120 HNDLE hKey;
02121 KEY key;
02122 char buffer[100000];
02123 DWORD bkname;
02124 WORD bktype;
02125
02126 event_def = db_get_event_definition(pevent->event_id);
02127 if (event_def == NULL)
02128 return SS_SUCCESS;
02129
02130
02131 pbuf = buffer;
02132 name[4] = 0;
02133
02134 if (pevent->event_id == EVENTID_BOR)
02135 sprintf(pbuf, "%%ID BOR NR %d\n", (int) pevent->serial_number);
02136 else if (pevent->event_id == EVENTID_EOR)
02137 sprintf(pbuf, "%%ID EOR NR %d\n", (int) pevent->serial_number);
02138 else
02139 sprintf(pbuf, "%%ID %d TR %d NR %d\n", pevent->event_id, pevent->trigger_mask,
02140 (int) pevent->serial_number);
02141 STR_INC(pbuf, buffer);
02142
02143
02144 if (event_def->format == FORMAT_MIDAS) {
02145 pbh = (BANK_HEADER *) (pevent + 1);
02146 pbk = NULL;
02147 pbk32 = NULL;
02148 do {
02149
02150 if (bk_is32(pbh)) {
02151 size = bk_iterate32(pbh, &pbk32, &pdata);
02152 if (pbk32 == NULL)
02153 break;
02154 bkname = *((DWORD *) pbk32->name);
02155 bktype = (WORD) pbk32->type;
02156 } else {
02157 size = bk_iterate(pbh, &pbk, &pdata);
02158 if (pbk == NULL)
02159 break;
02160 bkname = *((DWORD *) pbk->name);
02161 bktype = (WORD) pbk->type;
02162 }
02163
02164
02165 exclude = FALSE;
02166 pbl = NULL;
02167 if (par->bank_list != NULL)
02168 for (i = 0; par->bank_list[i].name[0]; i++)
02169 if (*((DWORD *) par->bank_list[i].name) == bkname) {
02170 pbl = &par->bank_list[i];
02171 exclude = (pbl->output_flag == 0);
02172 break;
02173 }
02174
02175 if (!exclude) {
02176 if (rpc_tid_size(bktype & 0xFF))
02177 size /= rpc_tid_size(bktype & 0xFF);
02178
02179 lrs1882 = (LRS1882_DATA *) pdata;
02180 lrs1877 = (LRS1877_DATA *) pdata;
02181
02182
02183 *((DWORD *) name) = bkname;
02184
02185 if ((bktype & 0xFF00) == 0)
02186 strcpy(type_name, rpc_tid_name(bktype & 0xFF));
02187 else if ((bktype & 0xFF00) == TID_LRS1882)
02188 strcpy(type_name, "LRS1882");
02189 else if ((bktype & 0xFF00) == TID_LRS1877)
02190 strcpy(type_name, "LRS1877");
02191 else if ((bktype & 0xFF00) == TID_PCOS3)
02192 strcpy(type_name, "PCOS3");
02193 else
02194 strcpy(type_name, "unknown");
02195
02196 sprintf(pbuf, "BK %s TP %s SZ %d\n", name, type_name, size);
02197 STR_INC(pbuf, buffer);
02198
02199 if (bktype == TID_STRUCT) {
02200 if (pbl == NULL)
02201 cm_msg(MERROR, "write_event_ascii", "received unknown bank %s", name);
02202 else
02203
02204 for (i = 0;; i++) {
02205 status = db_enum_key(hDB, pbl->def_key, i, &hKey);
02206 if (status == DB_NO_MORE_SUBKEYS)
02207 break;
02208
02209 db_get_key(hDB, hKey, &key);
02210 sprintf(pbuf, "%s:\n", key.name);
02211 STR_INC(pbuf, buffer);
02212
02213
02214 pdata =
02215 (void *) VALIGN(pdata,
02216 MIN(ss_get_struct_align(), key.item_size));
02217
02218 for (j = 0; j < key.num_values; j++) {
02219 db_sprintf(pbuf, pdata, key.item_size, j, key.type);
02220 strcat(pbuf, "\n");
02221 STR_INC(pbuf, buffer);
02222 }
02223
02224
02225 pdata = (char *) pdata + key.item_size * key.num_values;
02226 }
02227 } else {
02228
02229 if ((bktype & 0xFF00) == TID_LRS1877) {
02230 for (i = 0; i < size;) {
02231 lrs1877_header = (LRS1877_HEADER *) & lrs1877[i];
02232
02233
02234 sprintf(pbuf, "GA %d BF %d CN %d",
02235 lrs1877_header->geo_addr, lrs1877_header->buffer,
02236 lrs1877_header->count);
02237 strcat(pbuf, "\n");
02238 STR_INC(pbuf, buffer);
02239
02240 count = lrs1877_header->count;
02241 if (count == 0)
02242 break;
02243 for (j = 1; j < count; j++) {
02244
02245 sprintf(pbuf, "GA %d CH %02d ED %d DA %1.1lf",
02246 lrs1877[i].geo_addr, lrs1877[i + j].channel,
02247 lrs1877[i + j].edge, lrs1877[i + j].data * 0.5);
02248 strcat(pbuf, "\n");
02249 STR_INC(pbuf, buffer);
02250 }
02251
02252 i += count;
02253 }
02254 } else
02255 for (i = 0; i < size; i++) {
02256 if ((bktype & 0xFF00) == 0)
02257 db_sprintf(pbuf, pdata, size, i, bktype & 0xFF);
02258
02259 else if ((bktype & 0xFF00) == TID_LRS1882)
02260 sprintf(pbuf, "GA %d CH %02d DA %d",
02261 lrs1882[i].geo_addr, lrs1882[i].channel, lrs1882[i].data);
02262
02263 else if ((bktype & 0xFF00) == TID_PCOS3)
02264 sprintf(pbuf, "TBD");
02265 else
02266 db_sprintf(pbuf, pdata, size, i, bktype & 0xFF);
02267
02268 strcat(pbuf, "\n");
02269 STR_INC(pbuf, buffer);
02270 }
02271 }
02272 }
02273
02274 } while (1);
02275 }
02276
02277
02278 if (event_def->format == FORMAT_FIXED) {
02279 if (event_def->hDefKey == 0)
02280 cm_msg(MERROR, "write_event_ascii", "cannot find event definition");
02281 else {
02282 pdata = (char *) (pevent + 1);
02283 for (i = 0;; i++) {
02284 status = db_enum_key(hDB, event_def->hDefKey, i, &hKey);
02285 if (status == DB_NO_MORE_SUBKEYS)
02286 break;
02287
02288 db_get_key(hDB, hKey, &key);
02289 sprintf(pbuf, "%s\n", key.name);
02290 STR_INC(pbuf, buffer);
02291
02292
02293 pdata = (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
02294
02295 for (j = 0; j < key.num_values; j++) {
02296 db_sprintf(pbuf, pdata, key.item_size, j, key.type);
02297 strcat(pbuf, "\n");
02298 STR_INC(pbuf, buffer);
02299 }
02300
02301
02302 pdata = (char *) pdata + key.item_size * key.num_values;
02303 }
02304 }
02305 }
02306
02307
02308 strcat(pbuf, "\n");
02309 size = strlen(buffer);
02310
02311
02312 #ifdef HAVE_ZLIB
02313 if (out_gzip)
02314 status = gzwrite(file, buffer, size) == size ? SS_SUCCESS : SS_FILE_ERROR;
02315 else
02316 #endif
02317 status =
02318 fwrite(buffer, 1, size, file) == (size_t) size ? SS_SUCCESS : SS_FILE_ERROR;
02319
02320 return status;
02321 }
02322
02323
02324
02325 INT write_event_midas(FILE * file, EVENT_HEADER * pevent, ANALYZE_REQUEST * par)
02326 {
02327 INT status, size = 0, i;
02328 BOOL exclude;
02329 BANK_HEADER *pbh;
02330 BANK_LIST *pbl;
02331 EVENT_DEF *event_def;
02332 BANK *pbk;
02333 BANK32 *pbk32;
02334 char *pdata, *pdata_copy;
02335 char *pbuf;
02336 EVENT_HEADER *pevent_copy;
02337 DWORD bkname, bksize;
02338 WORD bktype;
02339 static char *buffer = NULL;
02340
02341 if (buffer == NULL)
02342 buffer = (char *) malloc(MAX_EVENT_SIZE);
02343
02344 pevent_copy = (EVENT_HEADER *) ALIGN8((POINTER_T) buffer);
02345
02346 if (clp.filter) {
02347
02348 size = pevent->data_size + sizeof(EVENT_HEADER);
02349 memcpy(pevent_copy, pevent, size);
02350 } else {
02351
02352
02353
02354
02355 event_def = db_get_event_definition(pevent->event_id);
02356 if (event_def == NULL)
02357 return SUCCESS;
02358
02359 if (event_def->format == FORMAT_MIDAS) {
02360
02361 pbuf = (char *) pevent_copy;
02362 memcpy(pbuf, pevent, sizeof(EVENT_HEADER));
02363 pbuf += sizeof(EVENT_HEADER);
02364
02365 pbh = (BANK_HEADER *) (pevent + 1);
02366
02367 if (bk_is32(pbh))
02368 bk_init32(pbuf);
02369 else
02370 bk_init(pbuf);
02371
02372 pbk = NULL;
02373 pbk32 = NULL;
02374 pdata_copy = pbuf;
02375 do {
02376
02377 if (bk_is32(pbh)) {
02378 size = bk_iterate32(pbh, &pbk32, &pdata);
02379 if (pbk32 == NULL)
02380 break;
02381 bkname = *((DWORD *) pbk32->name);
02382 bktype = (WORD) pbk32->type;
02383 bksize = pbk32->data_size;
02384 } else {
02385 size = bk_iterate(pbh, &pbk, &pdata);
02386 if (pbk == NULL)
02387 break;
02388 bkname = *((DWORD *) pbk->name);
02389 bktype = (WORD) pbk->type;
02390 bksize = pbk->data_size;
02391 }
02392
02393
02394 exclude = FALSE;
02395 pbl = NULL;
02396 if (par->bank_list != NULL)
02397 for (i = 0; par->bank_list[i].name[0]; i++)
02398 if (*((DWORD *) par->bank_list[i].name) == bkname) {
02399 pbl = &par->bank_list[i];
02400 exclude = (pbl->output_flag == 0);
02401 break;
02402 }
02403
02404 if (!exclude) {
02405
02406 bk_create(pbuf, (char *) (&bkname), bktype, &pdata_copy);
02407 memcpy(pdata_copy, pdata, bksize);
02408 pdata_copy += bksize;
02409 bk_close(pbuf, pdata_copy);
02410 }
02411
02412 } while (1);
02413
02414
02415 size = ALIGN8((POINTER_T) pdata_copy - (POINTER_T) pbuf);
02416 pevent_copy->data_size = size;
02417 size += sizeof(EVENT_HEADER);
02418 }
02419
02420
02421 if (event_def->format == FORMAT_FIXED) {
02422 size = pevent->data_size + sizeof(EVENT_HEADER);
02423 memcpy(pevent_copy, pevent, size);
02424 }
02425
02426 if (pevent_copy->data_size == 0)
02427 return SUCCESS;
02428 }
02429
02430
02431 #ifdef HAVE_ZLIB
02432 if (out_gzip)
02433 status = gzwrite(file, pevent_copy, size) == size ? SUCCESS : SS_FILE_ERROR;
02434 else
02435 #endif
02436 status =
02437 fwrite(pevent_copy, 1, size, file) == (size_t) size ? SUCCESS : SS_FILE_ERROR;
02438
02439 return status;
02440 }
02441
02442
02443
02444 #ifdef HAVE_HBOOK
02445
02446 INT write_event_hbook(FILE * file, EVENT_HEADER * pevent, ANALYZE_REQUEST * par)
02447 {
02448 INT i, j, k, n, size, item_size, status;
02449 BANK *pbk;
02450 BANK32 *pbk32;
02451 BANK_LIST *pbl;
02452 BANK_HEADER *pbh;
02453 char *pdata;
02454 BOOL exclude, exclude_all;
02455 char block_name[5], str[80];
02456 float rwnt[512];
02457 EVENT_DEF *event_def;
02458 HNDLE hkey;
02459 KEY key;
02460 DWORD bkname;
02461 WORD bktype;
02462
02463
02464 if (!ntuple_flag)
02465 return SS_SUCCESS;
02466
02467 event_def = db_get_event_definition(pevent->event_id);
02468 if (event_def == NULL)
02469 return SS_SUCCESS;
02470
02471 if (event_def->disabled)
02472 return SS_SUCCESS;
02473
02474
02475 if (clp.rwnt) {
02476 memset(rwnt, 0, sizeof(rwnt));
02477 rwnt[0] = (float) current_run_number;
02478 rwnt[1] = (float) pevent->serial_number;
02479 rwnt[2] = (float) pevent->time_stamp;
02480 } else {
02481 par->number.run = current_run_number;
02482 par->number.serial = pevent->serial_number;
02483 par->number.time = pevent->time_stamp;
02484 }
02485
02486
02487
02488 if (event_def->format == FORMAT_MIDAS) {
02489
02490 strcpy(str, "Number");
02491 if (!clp.rwnt)
02492 HFNTB(pevent->event_id, str);
02493
02494 pbk = NULL;
02495 pbk32 = NULL;
02496 exclude_all = TRUE;
02497 do {
02498 pbh = (BANK_HEADER *) (pevent + 1);
02499
02500 if (bk_is32(pbh)) {
02501 size = bk_iterate32(pbh, &pbk32, &pdata);
02502 if (pbk32 == NULL)
02503 break;
02504 bkname = *((DWORD *) pbk32->name);
02505 bktype = (WORD) pbk32->type;
02506 } else {
02507 size = bk_iterate(pbh, &pbk, &pdata);
02508 if (pbk == NULL)
02509 break;
02510 bkname = *((DWORD *) pbk->name);
02511 bktype = (WORD) pbk->type;
02512 }
02513
02514
02515 *((DWORD *) block_name) = bkname;
02516 block_name[4] = 0;
02517
02518 exclude = FALSE;
02519 pbl = NULL;
02520 if (par->bank_list != NULL) {
02521 for (i = 0; par->bank_list[i].name[0]; i++)
02522 if (*((DWORD *) par->bank_list[i].name) == bkname) {
02523 pbl = &par->bank_list[i];
02524 exclude = (pbl->output_flag == 0);
02525 break;
02526 }
02527 if (par->bank_list[i].name[0] == 0)
02528 cm_msg(MERROR, "write_event_hbook", "Received unknown bank %s",
02529 block_name);
02530 }
02531
02532
02533 if (!exclude && pbl != NULL && !clp.rwnt) {
02534
02535 if ((bktype & 0xFF) != TID_STRUCT) {
02536 item_size = rpc_tid_size(bktype & 0xFF);
02537 if (item_size == 0) {
02538 cm_msg(MERROR, "write_event_hbook",
02539 "Received bank %s with unknown item size", block_name);
02540 continue;
02541 }
02542
02543 pbl->n_data = size / item_size;
02544
02545
02546 if (pbl->n_data > pbl->size) {
02547 cm_msg(MERROR, "write_event_hbook",
02548 "Bank %s has more (%d) entries than maximum value (%d)",
02549 block_name, pbl->n_data, pbl->size);
02550 continue;
02551 }
02552
02553
02554 if (item_size >= 4) {
02555 size = MIN((INT) pbl->size * item_size, size);
02556 memcpy(pbl->addr, pdata, size);
02557 } else if (item_size == 2)
02558 for (i = 0; i < (INT) pbl->n_data; i++)
02559 *((DWORD *) pbl->addr + i) = (DWORD) * ((WORD *) pdata + i);
02560 else if (item_size == 1)
02561 for (i = 0; i < (INT) pbl->n_data; i++)
02562 *((DWORD *) pbl->addr + i) = (DWORD) * ((BYTE *) pdata + i);
02563 } else {
02564
02565 memcpy(pbl->addr, pdata, size);
02566 }
02567
02568
02569 HFNTB(pevent->event_id, block_name);
02570 }
02571
02572
02573 if (!exclude && pbl != NULL && clp.rwnt) {
02574 exclude_all = FALSE;
02575
02576 item_size = rpc_tid_size(bktype & 0xFF);
02577
02578 if ((bktype & 0xFF) != TID_STRUCT) {
02579 n = size / item_size;
02580
02581
02582 if (n > (INT) pbl->size) {
02583 cm_msg(MERROR, "write_event_hbook",
02584 "Bank %s has more (%d) entries than maximum value (%d)",
02585 block_name, n, pbl->size);
02586 continue;
02587 }
02588
02589
02590 for (i = 0; i < n; i++) {
02591 switch (bktype & 0xFF) {
02592 case TID_BYTE:
02593 rwnt[pbl->n_data + i] = (float) (*((BYTE *) pdata + i));
02594 break;
02595 case TID_WORD:
02596 rwnt[pbl->n_data + i] = (float) (*((WORD *) pdata + i));
02597 break;
02598 case TID_DWORD:
02599 rwnt[pbl->n_data + i] = (float) (*((DWORD *) pdata + i));
02600 break;
02601 case TID_FLOAT:
02602 rwnt[pbl->n_data + i] = (float) (*((float *) pdata + i));
02603 break;
02604 case TID_DOUBLE:
02605 rwnt[pbl->n_data + i] = (float) (*((double *) pdata + i));
02606 break;
02607 }
02608 }
02609
02610
02611 for (; i < (INT) pbl->size; i++)
02612 rwnt[pbl->n_data + i] = 0.f;
02613 } else {
02614
02615 k = pbl->n_data;
02616
02617 for (i = 0;; i++) {
02618 status = db_enum_key(hDB, pbl->def_key, i, &hkey);
02619 if (status == DB_NO_MORE_SUBKEYS)
02620 break;
02621
02622 db_get_key(hDB, hkey, &key);
02623
02624
02625 pdata =
02626 (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
02627
02628 for (j = 0; j < key.num_values; j++) {
02629 switch (key.type & 0xFF) {
02630 case TID_BYTE:
02631 rwnt[k++] = (float) (*((BYTE *) pdata + j));
02632 break;
02633 case TID_WORD:
02634 rwnt[k++] = (float) (*((WORD *) pdata + j));
02635 break;
02636 case TID_SHORT:
02637 rwnt[k++] = (float) (*((short int *) pdata + j));
02638 break;
02639 case TID_INT:
02640 rwnt[k++] = (float) (*((INT *) pdata + j));
02641 break;
02642 case TID_DWORD:
02643 rwnt[k++] = (float) (*((DWORD *) pdata + j));
02644 break;
02645 case TID_BOOL:
02646 rwnt[k++] = (float) (*((BOOL *) pdata + j));
02647 break;
02648 case TID_FLOAT:
02649 rwnt[k++] = (float) (*((float *) pdata + j));
02650 break;
02651 case TID_DOUBLE:
02652 rwnt[k++] = (float) (*((double *) pdata + j));
02653 break;
02654 }
02655 }
02656
02657
02658 pdata += key.item_size * key.num_values * sizeof(char);
02659 }
02660 }
02661 }
02662
02663 } while (TRUE);
02664
02665
02666 if (clp.rwnt && file != NULL && !exclude_all)
02667 HFN(pevent->event_id, rwnt);
02668
02669
02670 if (file == NULL)
02671 HFNOV(pevent->event_id, rwnt);
02672
02673 }
02674
02675
02676
02677
02678 else if (event_def->format == FORMAT_YBOS) {
02679 assert(!"YBOS not supported anymore");
02680 }
02681
02682
02683
02684 if (event_def->format == FORMAT_FIXED) {
02685 if (clp.rwnt) {
02686
02687 pdata = (char *) (pevent + 1);
02688 k = 3;
02689
02690 for (i = 0;; i++) {
02691 status = db_enum_key(hDB, event_def->hDefKey, i, &hkey);
02692 if (status == DB_NO_MORE_SUBKEYS)
02693 break;
02694
02695 db_get_key(hDB, hkey, &key);
02696
02697
02698 pdata = (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
02699
02700 for (j = 0; j < key.num_values; j++) {
02701 switch (key.type & 0xFF) {
02702 case TID_BYTE:
02703 rwnt[k++] = (float) (*((BYTE *) pdata + j));
02704 break;
02705 case TID_WORD:
02706 rwnt[k++] = (float) (*((WORD *) pdata + j));
02707 break;
02708 case TID_SHORT:
02709 rwnt[k++] = (float) (*((short int *) pdata + j));
02710 break;
02711 case TID_INT:
02712 rwnt[k++] = (float) (*((INT *) pdata + j));
02713 break;
02714 case TID_DWORD:
02715 rwnt[k++] = (float) (*((DWORD *) pdata + j));
02716 break;
02717 case TID_BOOL:
02718 rwnt[k++] = (float) (*((BOOL *) pdata + j));
02719 break;
02720 case TID_FLOAT:
02721 rwnt[k++] = (float) (*((float *) pdata + j));
02722 break;
02723 case TID_DOUBLE:
02724 rwnt[k++] = (float) (*((double *) pdata + j));
02725 break;
02726 }
02727 }
02728
02729
02730 pdata += key.item_size * key.num_values * sizeof(char);
02731 }
02732
02733
02734 if (file != NULL)
02735 HFN(pevent->event_id, rwnt);
02736
02737
02738 if (file == NULL)
02739 HFNOV(pevent->event_id, rwnt);
02740 } else {
02741 memcpy(par->addr, pevent + 1, pevent->data_size);
02742
02743
02744 HFNT(pevent->event_id);
02745 }
02746
02747 }
02748
02749 return SUCCESS;
02750 }
02751 #endif
02752
02753
02754
02755 #ifdef USE_ROOT
02756
02757 INT write_event_ttree(FILE * file, EVENT_HEADER * pevent, ANALYZE_REQUEST * par)
02758 {
02759 INT i, bklen;
02760 BANK *pbk;
02761 BANK32 *pbk32;
02762 BANK_LIST *pbl;
02763 BANK_HEADER *pbh;
02764 void *pdata;
02765 BOOL exclude, exclude_all;
02766 char bank_name[5];
02767 EVENT_DEF *event_def;
02768 DWORD bkname;
02769 WORD bktype;
02770 EVENT_TREE *et;
02771 TBranch *branch;
02772
02773
02774 if (!ntuple_flag)
02775 return SS_SUCCESS;
02776
02777 event_def = db_get_event_definition(pevent->event_id);
02778 if (event_def == NULL)
02779 return SS_SUCCESS;
02780
02781 if (event_def->disabled)
02782 return SS_SUCCESS;
02783
02784
02785 par->number.run = current_run_number;
02786 par->number.serial = pevent->serial_number;
02787 par->number.time = pevent->time_stamp;
02788
02789
02790
02791 if (event_def->format == FORMAT_MIDAS) {
02792
02793 for (i = 0; i < tree_struct.n_tree; i++)
02794 if (tree_struct.event_tree[i].event_id == pevent->event_id)
02795 break;
02796
02797 if (i == tree_struct.n_tree) {
02798 cm_msg(MERROR, "write_event_ttree", "Event #%d not booked by book_ttree()",
02799 pevent->event_id);
02800 return SS_INVALID_FORMAT;
02801 }
02802
02803 et = tree_struct.event_tree + i;
02804
02805
02806 for (i = 0; i < et->n_branch; i++)
02807 et->branch_filled[i] = FALSE;
02808
02809
02810 et->branch_filled[0] = TRUE;
02811
02812 pbk = NULL;
02813 pbk32 = NULL;
02814 exclude_all = TRUE;
02815 do {
02816 pbh = (BANK_HEADER *) (pevent + 1);
02817
02818 if (bk_is32(pbh)) {
02819 bklen = bk_iterate32(pbh, &pbk32, &pdata);
02820 if (pbk32 == NULL)
02821 break;
02822 bkname = *((DWORD *) pbk32->name);
02823 bktype = (WORD) pbk32->type;
02824 } else {
02825 bklen = bk_iterate(pbh, &pbk, &pdata);
02826 if (pbk == NULL)
02827 break;
02828 bkname = *((DWORD *) pbk->name);
02829 bktype = (WORD) pbk->type;
02830 }
02831
02832 if (rpc_tid_size(bktype & 0xFF))
02833 bklen /= rpc_tid_size(bktype & 0xFF);
02834
02835
02836 *((DWORD *) bank_name) = bkname;
02837 bank_name[4] = 0;
02838
02839 exclude = FALSE;
02840 pbl = NULL;
02841 if (par->bank_list != NULL) {
02842 for (i = 0; par->bank_list[i].name[0]; i++)
02843 if (*((DWORD *) par->bank_list[i].name) == bkname) {
02844 pbl = &par->bank_list[i];
02845 exclude = (pbl->output_flag == 0);
02846 break;
02847 }
02848 if (par->bank_list[i].name[0] == 0) {
02849 cm_msg(MERROR, "write_event_ttree", "Received unknown bank %s", bank_name);
02850 continue;
02851 }
02852 }
02853
02854
02855 if (!exclude && pbl != NULL) {
02856 for (i = 0; i < et->n_branch; i++)
02857 if (*((DWORD *) (&et->branch_name[i * NAME_LENGTH])) == bkname)
02858 break;
02859
02860 if (i == et->n_branch) {
02861 cm_msg(MERROR, "write_event_ttree", "Received unknown bank %s", bank_name);
02862 continue;
02863 }
02864
02865 exclude_all = FALSE;
02866 branch = et->branch[i];
02867 et->branch_filled[i] = TRUE;
02868 et->branch_len[i] = bklen;
02869
02870
02871 if ((bktype & 0xFF) != TID_STRUCT) {
02872 TIter next(branch->GetListOfLeaves());
02873 TLeaf *leaf = (TLeaf *) next();
02874
02875
02876 leaf->SetAddress(&et->branch_len[i]);
02877
02878 leaf = (TLeaf *) next();
02879 leaf->SetAddress(pdata);
02880 } else {
02881
02882 branch->SetAddress(pdata);
02883 }
02884 }
02885
02886 } while (TRUE);
02887
02888
02889 for (i = 0; i < et->n_branch; i++)
02890 if (!et->branch_filled[i])
02891 cm_msg(MERROR, "root_write",
02892 "Bank %s booked but not received, tree cannot be filled",
02893 et->branch_name + (i * NAME_LENGTH));
02894
02895
02896 #if (ROOT_VERSION_CODE < 262401)
02897 if (clp.online && et->tree->GetEntries() > par->rwnt_buffer_size)
02898 et->tree->Reset();
02899 #endif
02900
02901
02902 if (!exclude_all)
02903 et->tree->Fill();
02904
02905 }
02906
02907
02908
02909 if (event_def->format == FORMAT_FIXED) {
02910
02911 for (i = 0; i < tree_struct.n_tree; i++)
02912 if (tree_struct.event_tree[i].event_id == pevent->event_id)
02913 break;
02914
02915 if (i == tree_struct.n_tree) {
02916 cm_msg(MERROR, "write_event_ttree", "Event #%d not booked by book_ttree()",
02917 pevent->event_id);
02918 return SS_INVALID_FORMAT;
02919 }
02920
02921 et = tree_struct.event_tree + i;
02922
02923 et->tree->GetBranch(et->branch_name)->SetAddress(pevent + 1);
02924 et->tree->Fill();
02925 }
02926
02927 return SUCCESS;
02928 }
02929
02930 #endif
02931
02932
02933
02934 INT write_event_odb(EVENT_HEADER * pevent)
02935 {
02936 INT status, size, n_data, i;
02937 BANK_HEADER *pbh;
02938 EVENT_DEF *event_def;
02939 BANK *pbk;
02940 BANK32 *pbk32;
02941 void *pdata;
02942 char name[5];
02943 HNDLE hKeyRoot, hKey;
02944 KEY key;
02945 DWORD bkname;
02946 WORD bktype;
02947
02948 event_def = db_get_event_definition(pevent->event_id);
02949 if (event_def == NULL)
02950 return SS_SUCCESS;
02951
02952
02953
02954 if (event_def->format == FORMAT_MIDAS) {
02955 pbh = (BANK_HEADER *) (pevent + 1);
02956 pbk = NULL;
02957 pbk32 = NULL;
02958 do {
02959
02960 if (bk_is32(pbh)) {
02961 size = bk_iterate32(pbh, &pbk32, &pdata);
02962 if (pbk32 == NULL)
02963 break;
02964 bkname = *((DWORD *) pbk32->name);
02965 bktype = (WORD) pbk32->type;
02966 } else {
02967 size = bk_iterate(pbh, &pbk, &pdata);
02968 if (pbk == NULL)
02969 break;
02970 bkname = *((DWORD *) pbk->name);
02971 bktype = (WORD) pbk->type;
02972 }
02973
02974 n_data = size;
02975 if (rpc_tid_size(bktype & 0xFF))
02976 n_data /= rpc_tid_size(bktype & 0xFF);
02977
02978
02979 *((DWORD *) name) = bkname;
02980 name[4] = 0;
02981
02982 status = db_find_key(hDB, event_def->hDefKey, name, &hKeyRoot);
02983 if (status != DB_SUCCESS) {
02984 cm_msg(MERROR, "write_event_odb", "received unknown bank %s", name);
02985 continue;
02986 }
02987
02988 if (bktype == TID_STRUCT) {
02989
02990 for (i = 0;; i++) {
02991 status = db_enum_key(hDB, hKeyRoot, i, &hKey);
02992 if (status == DB_NO_MORE_SUBKEYS)
02993 break;
02994
02995 db_get_key(hDB, hKey, &key);
02996
02997
02998 if (key.type != TID_STRING && key.type != TID_LINK)
02999 pdata =
03000 (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
03001
03002 status = db_set_data(hDB, hKey, pdata, key.item_size * key.num_values,
03003 key.num_values, key.type);
03004 if (status != DB_SUCCESS) {
03005 cm_msg(MERROR, "write_event_odb", "cannot write %s to ODB", name);
03006 continue;
03007 }
03008
03009
03010 pdata = (char *) pdata + key.item_size * key.num_values;
03011 }
03012 } else {
03013 db_get_key(hDB, hKeyRoot, &key);
03014
03015
03016 if (n_data > 0) {
03017 status = db_set_data(hDB, hKeyRoot, pdata, size, n_data, key.type);
03018 if (status != DB_SUCCESS) {
03019 cm_msg(MERROR, "write_event_odb", "cannot write %s to ODB", name);
03020 continue;
03021 }
03022 }
03023 }
03024 } while (1);
03025 }
03026
03027
03028
03029 if (event_def->format == FORMAT_FIXED && !clp.online) {
03030 if (db_set_record
03031 (hDB, event_def->hDefKey, (char *) (pevent + 1), pevent->data_size,
03032 0) != DB_SUCCESS)
03033 cm_msg(MERROR, "write_event_odb", "event #%d size mismatch", pevent->event_id);
03034 }
03035
03036 return SUCCESS;
03037 }
03038
03039
03040
03041 static struct {
03042 short int event_id;
03043 DWORD last_time;
03044 } last_time_event[50];
03045
03046 ANALYZE_REQUEST *_current_par;
03047
03048 void correct_num_events(INT i)
03049 {
03050 if (_current_par)
03051 _current_par->events_received += i - 1;
03052 }
03053
03054 INT process_event(ANALYZE_REQUEST * par, EVENT_HEADER * pevent)
03055 {
03056 INT i, status = SUCCESS, ch;
03057 ANA_MODULE **module;
03058 DWORD actual_time;
03059 EVENT_DEF *event_def;
03060 static DWORD last_time_kb = 0;
03061 static char *orig_event = NULL;
03062
03063
03064 if (clp.verbose)
03065 printf("event %d, number %d, total size %d\n",
03066 (int) pevent->event_id,
03067 (int) pevent->serial_number,
03068 (int) (pevent->data_size + sizeof(EVENT_HEADER)));
03069
03070
03071 _current_par = par;
03072
03073
03074 actual_time = ss_millitime();
03075 if (!clp.online && actual_time - last_time_kb > 1000 && !clp.quiet && !pvm_slave) {
03076 last_time_kb = actual_time;
03077
03078 while (ss_kbhit()) {
03079 ch = ss_getchar(0);
03080 if (ch == -1)
03081 ch = getchar();
03082
03083 if ((char) ch == '!')
03084 return RPC_SHUTDOWN;
03085 }
03086 }
03087
03088 if (par == NULL) {
03089
03090 if (pevent->event_id == EVENTID_BOR) {
03091
03092 current_run_number = pevent->serial_number;
03093
03094 cm_msg(MINFO, "process_event", "Set run number %d in ODB", current_run_number);
03095 assert(current_run_number > 0);
03096
03097
03098 status = db_set_value(hDB, 0, "/Runinfo/Run number", ¤t_run_number,
03099 sizeof(current_run_number), 1, TID_INT);
03100 assert(status == SUCCESS);
03101
03102
03103 odb_load(pevent);
03104
03105 #ifdef HAVE_PVM
03106 PVM_DEBUG("process_event: ODB load");
03107 #endif
03108 }
03109 } else
03110
03111 par->events_received++;
03112
03113 #ifdef HAVE_PVM
03114
03115
03116 if (pvm_master) {
03117 status = pvm_distribute(par, pevent);
03118 return status;
03119 }
03120 #endif
03121
03122
03123 if (par == NULL)
03124 return SUCCESS;
03125
03126
03127 event_def = db_get_event_definition(pevent->event_id);
03128 if (event_def == NULL)
03129 return 0;
03130
03131 if (event_def->format == FORMAT_MIDAS)
03132 bk_swap((BANK_HEADER *) (pevent + 1), FALSE);
03133
03134
03135 if (clp.filter) {
03136 if (orig_event == NULL)
03137 orig_event = (char *) malloc(MAX_EVENT_SIZE + sizeof(EVENT_HEADER));
03138 memcpy(orig_event, pevent, pevent->data_size + sizeof(EVENT_HEADER));
03139 }
03140
03141
03142
03143
03144 if (par->analyzer) {
03145 status = par->analyzer(pevent, (void *) (pevent + 1));
03146
03147
03148 if (status == ANA_SKIP)
03149 return 0;
03150 }
03151
03152
03153 module = par->ana_module;
03154 for (i = 0; module != NULL && module[i] != NULL; i++) {
03155 if (module[i]->enabled) {
03156
03157 status = module[i]->analyzer(pevent, (void *) (pevent + 1));
03158
03159
03160 if (status == ANA_SKIP)
03161 return 0;
03162 }
03163 }
03164
03165 if (event_def->format == FORMAT_MIDAS) {
03166
03167 i = bk_size(pevent + 1);
03168 if (i > MAX_EVENT_SIZE)
03169 cm_msg(MERROR, "process_event", "Event got too large (%d Bytes) in analyzer", i);
03170
03171
03172 pevent->data_size = i;
03173 }
03174
03175 if (event_def->format == FORMAT_YBOS) {
03176 assert(!"YBOS not supported anymore");
03177 }
03178
03179
03180 if (par->use_tests)
03181 test_increment();
03182
03183
03184 if (clp.filter)
03185 pevent = (EVENT_HEADER *) orig_event;
03186
03187
03188 if (out_file) {
03189 #ifdef HAVE_HBOOK
03190 if (out_format == FORMAT_HBOOK)
03191 status = write_event_hbook(out_file, pevent, par);
03192 #endif
03193 #ifdef USE_ROOT
03194 if (out_format == FORMAT_ROOT)
03195 status = write_event_ttree(out_file, pevent, par);
03196 #endif
03197 if (out_format == FORMAT_ASCII)
03198 status = write_event_ascii(out_file, pevent, par);
03199 if (out_format == FORMAT_MIDAS)
03200 status = write_event_midas(out_file, pevent, par);
03201
03202 if (status != SUCCESS) {
03203 cm_msg(MERROR, "process_event", "Error writing to file (Disk full?)");
03204 return -1;
03205 }
03206
03207 par->events_written++;
03208 }
03209 #ifdef HAVE_HBOOK
03210
03211 if ((clp.online || equal_ustring(clp.output_file_name, "OFLN"))
03212 && par->rwnt_buffer_size > 0)
03213 write_event_hbook(NULL, pevent, par);
03214 #endif
03215 #ifdef USE_ROOT
03216
03217 if (clp.online && par->rwnt_buffer_size > 0)
03218 write_event_ttree(NULL, pevent, par);
03219 #endif
03220
03221
03222
03223 if (out_info.events_to_odb)
03224 for (i = 0; i < 50; i++) {
03225 if (last_time_event[i].event_id == pevent->event_id) {
03226 if (event_def->type == EQ_PERIODIC ||
03227 event_def->type == EQ_SLOW
03228 || actual_time - last_time_event[i].last_time > 1000) {
03229 last_time_event[i].last_time = actual_time;
03230 write_event_odb(pevent);
03231 }
03232 break;
03233 }
03234 if (last_time_event[i].event_id == 0) {
03235 last_time_event[i].event_id = pevent->event_id;
03236 last_time_event[i].last_time = actual_time;
03237 write_event_odb(pevent);
03238 break;
03239 }
03240 }
03241
03242 return SUCCESS;
03243 }
03244
03245
03246
03247 void receive_event(HNDLE buffer_handle, HNDLE request_id, EVENT_HEADER * pheader,
03248 void *pevent)
03249
03250 {
03251 INT i;
03252 ANALYZE_REQUEST *par;
03253 static DWORD buffer_size = 0;
03254 static char *buffer = NULL;
03255 char *pb;
03256
03257 if (buffer == NULL) {
03258 buffer = (char *) malloc(MAX_EVENT_SIZE + sizeof(EVENT_HEADER));
03259
03260 if (buffer == NULL) {
03261 cm_msg(MERROR, "receive_event", "Not enough memory to buffer event of size %d",
03262 buffer_size);
03263 return;
03264 }
03265 }
03266
03267
03268 pb = (char *) ALIGN8((POINTER_T) buffer);
03269
03270
03271 memcpy(pb, pheader, pheader->data_size + sizeof(EVENT_HEADER));
03272
03273 par = analyze_request;
03274
03275 for (i = 0; par->event_name[0]; par++)
03276 if (par->buffer_handle == buffer_handle && par->request_id == request_id) {
03277 process_event(par, (EVENT_HEADER *) pb);
03278 }
03279 }
03280
03281
03282
03283 void update_request(HNDLE hDB, HNDLE hKey, void *info)
03284 {
03285 AR_INFO *ar_info;
03286 INT i;
03287
03288 if (!clp.online)
03289 return;
03290
03291
03292 for (i = 0; analyze_request[i].event_name[0]; i++)
03293 if (analyze_request[i].hkey_common == hKey) {
03294 ar_info = &analyze_request[i].ar_info;
03295
03296
03297 if (analyze_request[i].request_id != -1)
03298 bm_delete_request(analyze_request[i].request_id);
03299
03300
03301 if (ar_info->enabled)
03302 bm_request_event(analyze_request[i].buffer_handle, (short) ar_info->event_id,
03303 (short) ar_info->trigger_mask, ar_info->sampling_type,
03304 &analyze_request[i].request_id, receive_event);
03305 else
03306 analyze_request[i].request_id = -1;
03307 }
03308
03309 }
03310
03311
03312
03313 void register_requests(void)
03314 {
03315 INT index, status;
03316 char str[256];
03317 AR_INFO *ar_info;
03318 AR_STATS *ar_stats;
03319 HNDLE hKey;
03320
03321
03322 for (index = 0; analyze_request[index].event_name[0]; index++) {
03323 ar_info = &analyze_request[index].ar_info;
03324 ar_stats = &analyze_request[index].ar_stats;
03325
03326
03327 sprintf(str, "/%s/%s/Common", analyzer_name, analyze_request[index].event_name);
03328 db_check_record(hDB, 0, str, ANALYZER_REQUEST_STR, TRUE);
03329 db_find_key(hDB, 0, str, &hKey);
03330 analyze_request[index].hkey_common = hKey;
03331
03332 strcpy(ar_info->client_name, analyzer_name);
03333 gethostname(ar_info->host, sizeof(ar_info->host));
03334 db_set_record(hDB, hKey, ar_info, sizeof(AR_INFO), 0);
03335
03336
03337 db_open_record(hDB, hKey, ar_info, sizeof(AR_INFO), MODE_READ, update_request,
03338 NULL);
03339
03340
03341 sprintf(str, "/%s/%s/Statistics", analyzer_name, analyze_request[index].event_name);
03342 db_check_record(hDB, 0, str, ANALYZER_STATS_STR, TRUE);
03343 db_find_key(hDB, 0, str, &hKey);
03344 assert(hKey);
03345
03346 ar_stats->events_received = 0;
03347 ar_stats->events_per_sec = 0;
03348 ar_stats->events_written = 0;
03349
03350
03351 status =
03352 db_open_record(hDB, hKey, ar_stats, sizeof(AR_STATS), MODE_WRITE, NULL, NULL);
03353 if (status != DB_SUCCESS)
03354 printf("Cannot open statistics record, probably other analyzer is using it\n");
03355
03356 if (clp.online) {
03357
03358 bm_open_buffer(ar_info->buffer, 2*MAX_EVENT_SIZE,
03359 &analyze_request[index].buffer_handle);
03360
03361
03362 bm_set_cache_size(analyze_request[index].buffer_handle, 100000, 0);
03363
03364
03365 if (ar_info->enabled)
03366 bm_request_event(analyze_request[index].buffer_handle,
03367 (short) ar_info->event_id, (short) ar_info->trigger_mask,
03368 ar_info->sampling_type, &analyze_request[index].request_id,
03369 receive_event);
03370 else
03371 analyze_request[index].request_id = -1;
03372 }
03373 }
03374 }
03375
03376
03377
03378 void update_stats()
03379 {
03380 int i;
03381 AR_STATS *ar_stats;
03382 static DWORD last_time = 0;
03383 DWORD actual_time;
03384
03385 actual_time = ss_millitime();
03386
03387 if (last_time == 0)
03388 last_time = actual_time;
03389
03390 if (actual_time - last_time == 0)
03391 return;
03392
03393 for (i = 0; analyze_request[i].event_name[0]; i++) {
03394 ar_stats = &analyze_request[i].ar_stats;
03395 ar_stats->events_received += analyze_request[i].events_received;
03396 ar_stats->events_written += analyze_request[i].events_written;
03397 ar_stats->events_per_sec =
03398 (analyze_request[i].events_received / ((actual_time - last_time) / 1000.0));
03399 analyze_request[i].events_received = 0;
03400 analyze_request[i].events_written = 0;
03401 }
03402
03403
03404 db_send_changed_records();
03405
03406
03407 test_write(actual_time - last_time);
03408
03409 last_time = actual_time;
03410 }
03411
03412
03413
03414 #ifdef USE_ROOT
03415
03416
03417
03418
03419
03420 TCutG *cut_book(const char *name)
03421 {
03422
03423
03424
03425 open_subfolder("cuts");
03426
03427 TFolder *folder(gHistoFolderStack->Last()? (TFolder *) gHistoFolderStack->
03428 Last() : gManaHistosFolder);
03429
03430 TCutG *cut((TCutG *) folder->FindObject(name));
03431
03432 if (!cut) {
03433 cut = new TCutG();
03434 cut->SetName(name);
03435 folder->Add(cut);
03436 }
03437
03438 close_subfolder();
03439 return cut;
03440 }
03441
03442 void open_subfolder(char *name)
03443 {
03444
03445 TFolder *current = (TFolder *) gHistoFolderStack->Last();
03446
03447 if (!current)
03448 current = gManaHistosFolder;
03449
03450
03451 TFolder *subfolder = 0;
03452
03453 TCollection *listOfSubFolders = current->GetListOfFolders();
03454 TIter iter(listOfSubFolders);
03455 while (TObject * obj = iter()) {
03456 if (strcmp(obj->GetName(), name) == 0 && obj->InheritsFrom("TFolder"))
03457 subfolder = (TFolder *) obj;
03458 }
03459
03460 if (!subfolder) {
03461 subfolder = new TFolder(name, name);
03462 current->Add(subfolder);
03463 }
03464
03465 gHistoFolderStack->Add(subfolder);
03466 }
03467
03468 void close_subfolder()
03469 {
03470 if (gHistoFolderStack->Last())
03471 gHistoFolderStack->Remove(gHistoFolderStack->Last());
03472 }
03473
03474 #endif
03475
03476
03477 #ifdef HAVE_HBOOK
03478 INT clear_histos_hbook(INT id1, INT id2)
03479 {
03480 INT i;
03481
03482 if (id1 != id2) {
03483 printf("Clear ID %d to ID %d\n", id1, id2);
03484 for (i = id1; i <= id2; i++)
03485 if (HEXIST(i))
03486 HRESET(i, bstr);
03487 } else {
03488 printf("Clear ID %d\n", id1);
03489 HRESET(id1, bstr);
03490 }
03491
03492 return SUCCESS;
03493 }
03494 #endif
03495
03496
03497
03498 void lock_histo(INT id)
03499 {
03500 INT i;
03501
03502 for (i = 0; i < 10000; i++)
03503 if (lock_list[i] == 0)
03504 break;
03505
03506 lock_list[i] = id;
03507 }
03508
03509
03510
03511 #ifdef HAVE_HBOOK
03512 INT ana_callback(INT index, void *prpc_param[])
03513 {
03514 if (index == RPC_ANA_CLEAR_HISTOS)
03515 clear_histos_hbook(CINT(0), CINT(1));
03516 return RPC_SUCCESS;
03517 }
03518 #endif
03519
03520
03521
03522 void load_last_histos()
03523 {
03524 char str[256];
03525
03526
03527 if (!clp.no_load) {
03528 strcpy(str, out_info.last_histo_filename);
03529
03530 if (strchr(str, DIR_SEPARATOR) == NULL)
03531 add_data_dir(str, out_info.last_histo_filename);
03532
03533 #ifdef HAVE_HBOOK
03534 {
03535 FILE *f;
03536 char str2[256];
03537 int i;
03538
03539 for (i = 0; i < (int) strlen(str); i++)
03540 if (isupper(str[i]))
03541 break;
03542
03543 if (i < (int) strlen(str)) {
03544 printf
03545 ("Error: Due to a limitation in HBOOK, directoy names may not contain uppercase\n");
03546 printf(" characters. Histogram loading from %s will not work.\n", str);
03547 } else {
03548 f = fopen(str, "r");
03549 if (f != NULL) {
03550 fclose(f);
03551 printf("Loading previous online histos from %s\n", str);
03552 strcpy(str2, "A");
03553 HRGET(0, str, str2);
03554
03555
03556 if (HEXIST(100000))
03557 HDELET(100000);
03558 }
03559 }
03560 }
03561 #endif
03562
03563 #ifdef USE_ROOT
03564 printf("Loading previous online histos from %s\n", str);
03565 LoadRootHistograms(gManaHistosFolder, str);
03566 #endif
03567 }
03568 }
03569
03570
03571
03572 void save_last_histos()
03573 {
03574 char str[256];
03575
03576
03577 strcpy(str, out_info.last_histo_filename);
03578 if (strchr(str, DIR_SEPARATOR) == NULL)
03579 add_data_dir(str, out_info.last_histo_filename);
03580
03581 printf("Saving current online histos to %s\n", str);
03582
03583 #ifdef HAVE_HBOOK
03584 {
03585 int i;
03586 char str2[256];
03587
03588 for (i = 0; i < (int) strlen(str); i++)
03589 if (isupper(str[i]))
03590 break;
03591
03592 if (i < (int) strlen(str)) {
03593 printf
03594 ("Error: Due to a limitation in HBOOK, directoy names may not contain uppercase\n");
03595 printf(" characters. Histogram saving to %s will not work.\n", str);
03596 } else {
03597 strcpy(str2, "NT");
03598 HRPUT(0, str, str2);
03599 }
03600 }
03601 #endif
03602
03603 #ifdef USE_ROOT
03604 SaveRootHistograms(gManaHistosFolder, str);
03605 #endif
03606
03607 }
03608
03609
03610
03611 INT loop_online()
03612 {
03613 INT status = SUCCESS;
03614 DWORD last_time_loop, last_time_update, actual_time;
03615 int ch;
03616
03617 printf("Running analyzer online. Stop with \"!\"\n");
03618
03619
03620 last_time_update = 0;
03621 last_time_loop = 0;
03622
03623 do {
03624
03625 actual_time = ss_millitime();
03626
03627 if (actual_time - last_time_update > 1000) {
03628
03629 update_stats();
03630 last_time_update = actual_time;
03631
03632
03633 ch = 0;
03634 while (ss_kbhit()) {
03635 ch = ss_getchar(0);
03636 if (ch == -1)
03637 ch = getchar();
03638
03639 if ((char) ch == '!')
03640 break;
03641 }
03642
03643 if ((char) ch == '!')
03644 break;
03645 }
03646
03647 if (analyzer_loop_period == 0)
03648 status = cm_yield(1000);
03649 else {
03650 if (actual_time - last_time_loop > (DWORD) analyzer_loop_period) {
03651 last_time_loop = actual_time;
03652 analyzer_loop();
03653 }
03654
03655 status = cm_yield(analyzer_loop_period);
03656 }
03657
03658 } while (status != RPC_SHUTDOWN && status != SS_ABORT);
03659
03660
03661 update_stats();
03662
03663 return status;
03664 }
03665
03666
03667
03668 INT init_module_parameters(BOOL bclose)
03669 {
03670 INT i, j, status, size;
03671 ANA_MODULE **module;
03672 char str[80];
03673 HNDLE hkey;
03674
03675 for (i = 0; analyze_request[i].event_name[0]; i++) {
03676 module = analyze_request[i].ana_module;
03677 for (j = 0; module != NULL && module[j] != NULL; j++) {
03678 if (module[j]->parameters != NULL) {
03679 sprintf(str, "/%s/Parameters/%s", analyzer_name, module[j]->name);
03680
03681 if (bclose) {
03682 db_find_key(hDB, 0, str, &hkey);
03683 db_close_record(hDB, hkey);
03684 } else {
03685 status = db_find_key(hDB, 0, str, &hkey);
03686 if (status == DB_SUCCESS) {
03687 db_get_record_size(hDB, hkey, 0, &size);
03688 if (size != module[j]->param_size)
03689 status = 0;
03690 }
03691 if (status != DB_SUCCESS && module[j]->init_str) {
03692 if (db_check_record(hDB, 0, str, strcomb((const char **)module[j]->init_str), TRUE) !=
03693 DB_SUCCESS) {
03694 cm_msg(MERROR, "init_module_parameters",
03695 "Cannot create/check \"%s\" parameters in ODB", str);
03696 return 0;
03697 }
03698 }
03699
03700 db_find_key(hDB, 0, str, &hkey);
03701 assert(hkey);
03702
03703 if (db_open_record(hDB, hkey, module[j]->parameters, module[j]->param_size,
03704 MODE_READ, NULL, NULL) != DB_SUCCESS) {
03705 cm_msg(MERROR, "init_module_parameters",
03706 "Cannot open \"%s\" parameters in ODB", str);
03707 return 0;
03708 }
03709 }
03710 }
03711 }
03712 }
03713
03714 return SUCCESS;
03715 }
03716
03717
03718 void odb_load(EVENT_HEADER * pevent)
03719 {
03720 BOOL flag;
03721 int size, i, status;
03722 char str[256];
03723 HNDLE hKey, hKeyRoot, hKeyEq;
03724
03725 flag = TRUE;
03726 size = sizeof(flag);
03727 sprintf(str, "/%s/ODB Load", analyzer_name);
03728 db_get_value(hDB, 0, str, &flag, &size, TID_BOOL, TRUE);
03729
03730 if (flag) {
03731 for (i = 0; i < 10; i++)
03732 if (clp.protect[i][0] && !clp.quiet)
03733 printf("Protect ODB tree \"%s\"\n", clp.protect[i]);
03734
03735 if (!clp.quiet)
03736 printf("Load ODB from run %d...", (int) current_run_number);
03737
03738 if (flag == 1) {
03739
03740 db_set_mode(hDB, 0, MODE_READ, TRUE);
03741
03742 db_find_key(hDB, 0, "/Experiment/Run Parameters", &hKey);
03743 if (hKey)
03744 db_set_mode(hDB, hKey, MODE_READ | MODE_WRITE | MODE_DELETE, TRUE);
03745
03746
03747 sprintf(str, "/%s/Parameters", analyzer_name);
03748 db_find_key(hDB, 0, str, &hKey);
03749 if (hKey)
03750 db_set_mode(hDB, hKey, MODE_READ | MODE_WRITE | MODE_DELETE, TRUE);
03751
03752
03753 db_find_key(hDB, 0, "/Equipment", &hKeyRoot);
03754 if (hKeyRoot) {
03755 db_set_mode(hDB, hKeyRoot, MODE_READ | MODE_WRITE | MODE_DELETE, FALSE);
03756
03757 for (i = 0;; i++) {
03758 status = db_enum_key(hDB, hKeyRoot, i, &hKeyEq);
03759 if (status == DB_NO_MORE_SUBKEYS)
03760 break;
03761
03762 db_set_mode(hDB, hKeyEq, MODE_READ | MODE_WRITE | MODE_DELETE, TRUE);
03763
03764 db_find_key(hDB, hKeyEq, "Variables", &hKey);
03765 if (hKey)
03766 db_set_mode(hDB, hKey, MODE_READ, TRUE);
03767 }
03768 }
03769
03770
03771 for (i = 0; i < 10; i++)
03772 if (clp.protect[i][0]) {
03773 db_find_key(hDB, 0, clp.protect[i], &hKey);
03774 if (hKey)
03775 db_set_mode(hDB, hKey, MODE_READ, TRUE);
03776 }
03777 }
03778
03779
03780 init_module_parameters(TRUE);
03781
03782 if (strncmp((char *) (pevent + 1), "<?xml version=\"1.0\"", 19) == 0)
03783 db_paste_xml(hDB, 0, (char *) (pevent + 1));
03784 else
03785 db_paste(hDB, 0, (char *) (pevent + 1));
03786
03787 if (flag == 1)
03788 db_set_mode(hDB, 0, MODE_READ | MODE_WRITE | MODE_DELETE, TRUE);
03789
03790
03791 analyzer_init();
03792
03793
03794 if (!clp.quiet)
03795 printf("OK\n");
03796 load_parameters(current_run_number);
03797
03798
03799 init_module_parameters(FALSE);
03800 }
03801 }
03802
03803
03804
03805 #define MA_DEVICE_DISK 1
03806 #define MA_DEVICE_TAPE 2
03807 #define MA_DEVICE_FTP 3
03808 #define MA_DEVICE_PVM 4
03809
03810 #define MA_FORMAT_MIDAS (1<<0)
03811 #define MA_FORMAT_YBOS (1<<2)
03812 #define MA_FORMAT_GZIP (1<<3)
03813
03814 typedef struct {
03815 char file_name[256];
03816 int format;
03817 int device;
03818 int fd;
03819 #ifdef HAVE_ZLIB
03820 gzFile gzfile;
03821 #else
03822 FILE *file;
03823 #endif
03824 char *buffer;
03825 int wp, rp;
03826
03827 } MA_FILE;
03828
03829
03830
03831 MA_FILE *ma_open(char *file_name)
03832 {
03833 char *ext_str;
03834 int status;
03835 MA_FILE *file;
03836
03837
03838 file = (MA_FILE *) calloc(sizeof(MA_FILE), 1);
03839 if (file == NULL) {
03840 cm_msg(MERROR, "ma_open", "Cannot allocate MA file structure");
03841 return NULL;
03842 }
03843
03844
03845 strcpy(file->file_name, file_name);
03846
03847
03848 file->device = MA_DEVICE_DISK;
03849
03850
03851 if (pvm_slave) {
03852 file->device = MA_DEVICE_PVM;
03853 file->buffer = (char *) malloc(PVM_BUFFER_SIZE);
03854 file->wp = file->rp = 0;
03855 }
03856
03857
03858 if (strchr(file_name, '.')) {
03859 ext_str = file_name + strlen(file_name) - 1;
03860 while (*ext_str != '.')
03861 ext_str--;
03862 } else
03863 ext_str = "";
03864
03865 if (strncmp(ext_str, ".gz", 3) == 0) {
03866 #ifdef HAVE_ZLIB
03867 ext_str--;
03868 while (*ext_str != '.' && ext_str > file_name)
03869 ext_str--;
03870 #else
03871 cm_msg(MERROR, "ma_open",
03872 ".gz extension not possible because zlib support is not compiled in.\n");
03873 return NULL;
03874 #endif
03875 }
03876
03877 if (strncmp(file_name, "/dev/", 4) == 0)
03878 file->format = MA_FORMAT_MIDAS;
03879 else if (strncmp(ext_str, ".mid", 4) == 0)
03880 file->format = MA_FORMAT_MIDAS;
03881 else if (strncmp(ext_str, ".ybs", 4) == 0)
03882 assert(!"YBOS not supported anymore");
03883 else {
03884 printf
03885 ("Unknown input data format \"%s\". Please use file extension .mid or mid.gz.\n",
03886 ext_str);
03887 return NULL;
03888 }
03889
03890 if (file->device == MA_DEVICE_DISK) {
03891 if (file->format == MA_FORMAT_YBOS) {
03892 assert(!"YBOS not supported anymore");
03893 } else {
03894 #ifdef HAVE_ZLIB
03895 file->gzfile = gzopen(file_name, "rb");
03896 if (file->gzfile == NULL)
03897 return NULL;
03898 #else
03899 file->file = fopen(file_name, "rb");
03900 if (file->file == NULL)
03901 return NULL;
03902 #endif
03903 }
03904 }
03905
03906 return file;
03907 }
03908
03909
03910
03911 int ma_close(MA_FILE * file)
03912 {
03913 if (file->format == MA_FORMAT_YBOS)
03914 assert(!"YBOS not supported anymore");
03915 else
03916 #ifdef HAVE_ZLIB
03917 gzclose(file->gzfile);
03918 #else
03919 fclose(file->file);
03920 #endif
03921
03922 free(file);
03923 return SUCCESS;
03924 }
03925
03926
03927
03928 int ma_read_event(MA_FILE * file, EVENT_HEADER * pevent, int size)
03929 {
03930 int status, n;
03931
03932 if (file->device == MA_DEVICE_DISK) {
03933 if (file->format == MA_FORMAT_MIDAS) {
03934 if (size < (int) sizeof(EVENT_HEADER)) {
03935 cm_msg(MERROR, "ma_read_event", "Buffer size too small");
03936 return -1;
03937 }
03938
03939
03940 #ifdef HAVE_ZLIB
03941 n = gzread(file->gzfile, pevent, sizeof(EVENT_HEADER));
03942 #else
03943 n = sizeof(EVENT_HEADER)*fread(pevent, sizeof(EVENT_HEADER), 1, file->file);
03944 #endif
03945
03946 if (n < (int) sizeof(EVENT_HEADER)) {
03947 if (n > 0)
03948 printf("Unexpected end of file %s, last event skipped\n", file->file_name);
03949 return -1;
03950 }
03951
03952
03953 #ifdef SWAP_EVENTS
03954 WORD_SWAP(&pevent->event_id);
03955 WORD_SWAP(&pevent->trigger_mask);
03956 DWORD_SWAP(&pevent->serial_number);
03957 DWORD_SWAP(&pevent->time_stamp);
03958 DWORD_SWAP(&pevent->data_size);
03959 #endif
03960
03961
03962 n = 0;
03963 if (pevent->data_size > 0) {
03964 if (size < (int) pevent->data_size + (int) sizeof(EVENT_HEADER)) {
03965 cm_msg(MERROR, "ma_read_event", "Buffer size too small");
03966 return -1;
03967 }
03968 #ifdef HAVE_ZLIB
03969 n = gzread(file->gzfile, pevent + 1, pevent->data_size);
03970 #else
03971 n = pevent->data_size*fread(pevent + 1, pevent->data_size, 1, file->file);
03972 #endif
03973 if (n != (INT) pevent->data_size) {
03974 printf("Unexpected end of file %s, last event skipped\n", file->file_name);
03975 return -1;
03976 }
03977 }
03978
03979 return n + sizeof(EVENT_HEADER);
03980 } else if (file->format == MA_FORMAT_YBOS) {
03981 assert(!"YBOS not supported anymore");
03982 }
03983 } else if (file->device == MA_DEVICE_PVM) {
03984 #ifdef HAVE_PVM
03985 int bufid, len, tag, tid;
03986 EVENT_HEADER *pe;
03987 struct timeval timeout;
03988
03989
03990 if (file->wp > file->rp) {
03991 pe = (EVENT_HEADER *) (file->buffer + file->rp);
03992 size = sizeof(EVENT_HEADER) + pe->data_size;
03993 memcpy(pevent, pe, size);
03994 file->rp += size;
03995 return size;
03996 }
03997
03998
03999 pvm_initsend(PvmDataInPlace);
04000 pvm_send(pvm_myparent, TAG_DATA);
04001
04002
04003 timeout.tv_sec = 60;
04004 timeout.tv_usec = 0;
04005
04006 bufid = pvm_trecv(-1, -1, &timeout);
04007 if (bufid < 0) {
04008 pvm_perror("pvm_recv");
04009 return -1;
04010 }
04011 if (bufid == 0) {
04012 PVM_DEBUG("ma_read_event: timeout receiving data, aborting analyzer.\n");
04013 return -1;
04014 }
04015
04016 status = pvm_bufinfo(bufid, &len, &tag, &tid);
04017 if (status < 0) {
04018 pvm_perror("pvm_bufinfo");
04019 return -1;
04020 }
04021
04022 PVM_DEBUG("ma_read_event: receive tag %d, buflen %d", tag, len);
04023
04024 if (tag == TAG_EOR || tag == TAG_EXIT)
04025 return -1;
04026
04027 file->wp = len;
04028 file->rp = 0;
04029 status = pvm_upkbyte((char *) file->buffer, len, 1);
04030 if (status < 0) {
04031 pvm_perror("pvm_upkbyte");
04032 return -1;
04033 }
04034
04035
04036 if (len == 0)
04037 ss_sleep(200);
04038
04039
04040 return ma_read_event(file, pevent, size);
04041 #endif
04042 }
04043
04044 return 0;
04045 }
04046
04047
04048
04049 INT analyze_run(INT run_number, char *input_file_name, char *output_file_name)
04050 {
04051 EVENT_HEADER *pevent, *pevent_unaligned;
04052 ANALYZE_REQUEST *par;
04053 INT i, n, size;
04054 DWORD num_events_in, num_events_out;
04055 char error[256], str[256];
04056 INT status = SUCCESS;
04057 MA_FILE *file;
04058 BOOL skip;
04059 DWORD start_time;
04060
04061
04062 sprintf(str, "/%s/Output/Filename", analyzer_name);
04063 db_set_value(hDB, 0, str, output_file_name, 256, 1, TID_STRING);
04064 #ifdef HAVE_HBOOK
04065 sprintf(str, "/%s/Output/RWNT", analyzer_name);
04066 db_set_value(hDB, 0, str, &clp.rwnt, sizeof(BOOL), 1, TID_BOOL);
04067 #endif
04068
04069 assert(run_number > 0);
04070
04071
04072 status =
04073 db_set_value(hDB, 0, "/Runinfo/Run number", &run_number, sizeof(run_number), 1,
04074 TID_INT);
04075 assert(status == SUCCESS);
04076
04077
04078 strcpy(out_info.filename, output_file_name);
04079
04080
04081 cm_yield(0);
04082
04083
04084 file = ma_open(input_file_name);
04085 if (file == NULL) {
04086 printf("Cannot open input file \"%s\"\n", input_file_name);
04087 return -1;
04088 }
04089
04090 pevent_unaligned = (EVENT_HEADER *) malloc(EXT_EVENT_SIZE);
04091 if (pevent_unaligned == NULL) {
04092 printf("Not enough memeory\n");
04093 return -1;
04094 }
04095 pevent = (EVENT_HEADER *) ALIGN8((POINTER_T) pevent_unaligned);
04096
04097
04098 bor(run_number, error);
04099
04100 num_events_in = num_events_out = 0;
04101
04102 start_time = ss_millitime();
04103
04104
04105 do {
04106
04107 n = ma_read_event(file, pevent, EXT_EVENT_SIZE);
04108 if (n <= 0)
04109 break;
04110
04111 num_events_in++;
04112
04113
04114 if (pevent->event_id < 0) {
04115 status = process_event(NULL, pevent);
04116 if (status < 0 || status == RPC_SHUTDOWN)
04117 break;
04118
04119 if (out_file && out_format == FORMAT_MIDAS) {
04120 size = pevent->data_size + sizeof(EVENT_HEADER);
04121 #ifdef HAVE_ZLIB
04122 if (out_gzip)
04123 status = gzwrite(out_file, pevent, size) == size ? SUCCESS : SS_FILE_ERROR;
04124 else
04125 #endif
04126 status =
04127 fwrite(pevent, 1, size,
04128 out_file) == (size_t) size ? SUCCESS : SS_FILE_ERROR;
04129
04130 if (status != SUCCESS) {
04131 cm_msg(MERROR, "analyze_run", "Error writing to file (Disk full?)");
04132 return -1;
04133 }
04134
04135 num_events_out++;
04136 }
04137
04138
04139 if (pevent->event_id == EVENTID_BOR)
04140 start_time = ss_millitime();
04141 }
04142
04143
04144 skip = FALSE;
04145
04146 if (!pvm_slave) {
04147 if (clp.n[0] > 0 || clp.n[1] > 0) {
04148 if (clp.n[1] == 0) {
04149
04150 if (num_events_in > clp.n[0]) {
04151 num_events_in--;
04152 status = SUCCESS;
04153 break;
04154 }
04155 } else {
04156 if (num_events_in > clp.n[1]) {
04157 status = SUCCESS;
04158 break;
04159 }
04160 if (num_events_in < clp.n[0])
04161 skip = TRUE;
04162 else if (clp.n[2] > 0 && num_events_in % clp.n[2] != 0)
04163 skip = TRUE;
04164 }
04165 }
04166 }
04167
04168 if (!skip) {
04169
04170 par = analyze_request;
04171 status = SUCCESS;
04172 for (i = 0; par->event_name[0]; par++)
04173 if ((par->ar_info.event_id == EVENTID_ALL ||
04174 par->ar_info.event_id == pevent->event_id) &&
04175 (par->ar_info.trigger_mask == TRIGGER_ALL ||
04176 (par->ar_info.trigger_mask & pevent->trigger_mask))
04177 && par->ar_info.enabled) {
04178
04179 status = process_event(par, pevent);
04180 if (status == SUCCESS)
04181 num_events_out++;
04182 if (status < 0 || status == RPC_SHUTDOWN)
04183 break;
04184
04185
04186 status = cm_yield(0);
04187 }
04188 if (status < 0 || status == RPC_SHUTDOWN)
04189 break;
04190 }
04191
04192
04193 if (num_events_in % 100 == 0) {
04194 update_stats();
04195 if (!clp.quiet) {
04196 if (out_file)
04197 printf("%s:%d %s:%d events\r", input_file_name, (int) num_events_in,
04198 out_info.filename, (int) num_events_out);
04199 else
04200 printf("%s:%d events\r", input_file_name, (int) num_events_in);
04201
04202 #ifndef OS_WINNT
04203 fflush(stdout);
04204 #endif
04205 }
04206 }
04207 } while (1);
04208
04209 #ifdef HAVE_PVM
04210 PVM_DEBUG("analyze_run: event loop finished, status = %d", status);
04211 #endif
04212
04213
04214 #ifdef HAVE_PVM
04215 if (pvm_master) {
04216 if (status == RPC_SHUTDOWN)
04217 printf("\nShutting down distributed analyzers, please wait...\n");
04218 pvm_eor(status == RPC_SHUTDOWN ? TAG_EXIT : TAG_EOR);
04219
04220
04221 if (out_info.filename[0] && !out_append)
04222 status = pvm_merge();
04223
04224 start_time = ss_millitime() - start_time;
04225
04226 update_stats();
04227 if (!clp.quiet) {
04228 if (out_file)
04229 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, num_events_in,
04230 out_info.filename, num_events_out, start_time / 1000.0);
04231 else
04232 printf("%s:%d events, %1.2lfs\n", input_file_name, num_events_in,
04233 start_time / 1000.0);
04234 }
04235 } else if (pvm_slave) {
04236 start_time = ss_millitime() - start_time;
04237
04238 update_stats();
04239 if (!clp.quiet) {
04240 if (out_file)
04241 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, num_events_in,
04242 out_info.filename, num_events_out, start_time / 1000.0);
04243 else
04244 printf("%s:%d events, %1.2lfs\n", input_file_name, num_events_in,
04245 start_time / 1000.0);
04246 }
04247
04248 eor(current_run_number, error);
04249
04250
04251 pvm_initsend(PvmDataInPlace);
04252
04253 for (i = 0; i < n_test; i++)
04254 pvm_pkbyte((char *) tl[i], sizeof(ANA_TEST), 1);
04255
04256 PVM_DEBUG("analyze_run: send %d tests back to master", n_test);
04257
04258 status = pvm_send(pvm_myparent, TAG_EOR);
04259 if (status < 0) {
04260 pvm_perror("pvm_send");
04261 return RPC_SHUTDOWN;
04262 }
04263 } else {
04264 start_time = ss_millitime() - start_time;
04265
04266 update_stats();
04267 if (!clp.quiet) {
04268 if (out_file)
04269 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, num_events_in,
04270 out_info.filename, num_events_out, start_time / 1000.0);
04271 else
04272 printf("%s:%d events, %1.2lfs\n", input_file_name, num_events_in,
04273 start_time / 1000.0);
04274 }
04275
04276
04277 eor(current_run_number, error);
04278 }
04279 #else
04280
04281 start_time = ss_millitime() - start_time;
04282
04283 update_stats();
04284 if (!clp.quiet) {
04285 if (out_file)
04286 printf("%s:%d %s:%d events, %1.2lfs\n", input_file_name, (int) num_events_in,
04287 out_info.filename, (int) num_events_out, start_time / 1000.0);
04288 else
04289 printf("%s:%d events, %1.2lfs\n", input_file_name, (int) num_events_in,
04290 start_time / 1000.0);
04291 }
04292
04293
04294 eor(current_run_number, error);
04295
04296 #endif
04297
04298 ma_close(file);
04299
04300 free(pevent_unaligned);
04301
04302 return status;
04303 }
04304
04305
04306
04307 INT loop_runs_offline()
04308 {
04309 INT i, status, run_number;
04310 char input_file_name[256], output_file_name[256], *prn;
04311 BANK_LIST *bank_list;
04312
04313 if (!clp.quiet)
04314 printf("Running analyzer offline. Stop with \"!\"\n");
04315
04316 run_number = 0;
04317 out_append = ((strchr(clp.input_file_name[0], '%') != NULL) &&
04318 (strchr(clp.output_file_name, '%') == NULL))
04319 || clp.input_file_name[1][0];
04320
04321
04322 if (clp.run_number[0] > 0) {
04323 if (strchr(clp.input_file_name[0], '%') == NULL) {
04324 printf
04325 ("Input file name must contain a wildcard like \"%%05d\" when using a range.\n");
04326 return 0;
04327 }
04328
04329 if (clp.run_number[0] == 0) {
04330 printf("End of range not specified.\n");
04331 return 0;
04332 }
04333
04334 for (run_number = clp.run_number[0]; run_number <= clp.run_number[1]; run_number++) {
04335 sprintf(input_file_name, clp.input_file_name[0], run_number);
04336 if (strchr(clp.output_file_name, '%') != NULL)
04337 sprintf(output_file_name, clp.output_file_name, run_number);
04338 else
04339 strcpy(output_file_name, clp.output_file_name);
04340
04341 status = analyze_run(run_number, input_file_name, output_file_name);
04342 if (status == RPC_SHUTDOWN)
04343 break;
04344 }
04345 } else {
04346
04347 for (i = 0; clp.input_file_name[i][0] && i < 10; i++) {
04348 strcpy(input_file_name, clp.input_file_name[i]);
04349
04350
04351 prn = input_file_name;
04352 while (strchr(prn, DIR_SEPARATOR) != NULL)
04353 prn = strchr(prn, DIR_SEPARATOR) + 1;
04354
04355 if (strpbrk(prn, "0123456789"))
04356 run_number = atoi(strpbrk(prn, "0123456789"));
04357
04358 if (strchr(clp.output_file_name, '%') != NULL) {
04359 if (run_number == 0) {
04360 printf("Cannot extract run number from input file name.\n");
04361 return 0;
04362 }
04363 sprintf(output_file_name, clp.output_file_name, run_number);
04364 } else
04365 strcpy(output_file_name, clp.output_file_name);
04366
04367 status = analyze_run(run_number, input_file_name, output_file_name);
04368 if (status == RPC_SHUTDOWN)
04369 break;
04370 }
04371 }
04372
04373
04374 if (out_file && out_append) {
04375 if (out_format == FORMAT_HBOOK) {
04376 #ifdef HAVE_HBOOK
04377 char str[80];
04378
04379 HROUT(0, i, bstr);
04380 strcpy(str, "OFFLINE");
04381 HREND(str);
04382 #else
04383 cm_msg(MERROR, "loop_runs_offline", "HBOOK support is not compiled in");
04384 #endif
04385 } else if (out_format == FORMAT_ROOT) {
04386 #ifdef USE_ROOT
04387 CloseRootOutputFile();
04388 #else
04389 cm_msg(MERROR, "loop_runs_offline", "ROOT support is not compiled in");
04390 #endif
04391 } else {
04392 #ifdef HAVE_ZLIB
04393 if (out_gzip)
04394 gzclose(out_file);
04395 else
04396 #endif
04397 fclose(out_file);
04398 }
04399
04400
04401 for (i = 0; analyze_request[i].event_name[0]; i++) {
04402 bank_list = analyze_request[i].bank_list;
04403
04404 if (bank_list == NULL)
04405 continue;
04406
04407 for (; bank_list->name[0]; bank_list++)
04408 if (bank_list->addr) {
04409 free(bank_list->addr);
04410 bank_list->addr = NULL;
04411 }
04412 }
04413 }
04414 #ifdef HAVE_PVM
04415
04416 if (pvm_master && out_info.filename[0] && out_append)
04417 pvm_merge();
04418 #endif
04419
04420 return CM_SUCCESS;
04421 }
04422
04423
04424
04425 #ifdef HAVE_PVM
04426
04427 int pvm_main(char *argv[])
04428 {
04429 int mytid, status, i, j, dtid, *pvm_tid, bufid;
04430 char path[256];
04431 struct timeval timeout;
04432
04433 getcwd(path, 256);
04434
04435 mytid = pvm_mytid();
04436 if (mytid < 0) {
04437 pvm_perror("pvm_mytid");
04438 return 0;
04439 }
04440
04441 chdir(path);
04442
04443 status = pvm_setopt(PvmRoute, PvmRouteDirect);
04444 if (status < 0) {
04445 pvm_perror("pvm_setopt");
04446 pvm_exit();
04447 return 0;
04448 }
04449
04450 pvm_myparent = pvm_parent();
04451 if (pvm_myparent < 0 && pvm_myparent != PvmNoParent) {
04452 pvm_perror("pvm_parent");
04453 pvm_exit();
04454 return 0;
04455 }
04456
04457
04458 if (pvm_myparent == PvmNoParent) {
04459 struct pvmhostinfo *hostp;
04460 int n_host, n_arch;
04461
04462 #ifdef WIN32
04463 char *p;
04464
04465
04466 p = argv[0] + strlen(argv[0]) - 1;
04467 while (p > argv[0] && *p != '\\')
04468 p--;
04469 if (*p == '\\')
04470 p++;
04471 strcpy(path, p);
04472 #else
04473 if (strchr(argv[0], '/') == 0) {
04474 getcwd(path, 256);
04475 strcat(path, "/");
04476 strcat(path, argv[0]);
04477 } else
04478 strcpy(path, argv[0]);
04479 #endif
04480
04481
04482 if (clp.n_task == -1)
04483 return SUCCESS;
04484
04485
04486 pvm_config(&n_host, &n_arch, &hostp);
04487
04488 pvm_n_task = n_host - 1;
04489 if (clp.n_task != 0)
04490 pvm_n_task = clp.n_task;
04491
04492 if (clp.n_task != 1 && pvm_n_task > n_host - 1)
04493 pvm_n_task = n_host - 1;
04494
04495 if (pvm_n_task == 0)
04496 return SUCCESS;
04497
04498 pvm_master = TRUE;
04499
04500 pvm_tid = malloc(sizeof(int) * pvm_n_task);
04501 pvmc = malloc(sizeof(PVM_CLIENT) * pvm_n_task);
04502
04503 if (pvm_tid == NULL || pvmc == NULL) {
04504 free(pvm_tid);
04505 printf("Not enough memory to allocate PVM structures.\n");
04506 pvm_exit();
04507 return 0;
04508 }
04509
04510 memset(pvmc, 0, sizeof(PVM_CLIENT) * pvm_n_task);
04511
04512 for (i = 0; i < pvm_n_task; i++) {
04513 pvmc[i].buffer = malloc(PVM_BUFFER_SIZE);
04514 if (pvmc[i].buffer == NULL) {
04515 free(pvm_tid);
04516 free(pvmc);
04517 printf("Not enough memory to allocate PVM buffers.\n");
04518 pvm_exit();
04519 return 0;
04520 }
04521 }
04522
04523
04524 printf("Parallelizing analyzer on %d machines\n", pvm_n_task);
04525 if (pvm_n_task == 1)
04526 status = pvm_spawn(path, argv + 1, PvmTaskDefault, NULL, pvm_n_task, pvm_tid);
04527 else
04528 status =
04529 pvm_spawn(path, argv + 1, PvmTaskHost | PvmHostCompl, ".", pvm_n_task,
04530 pvm_tid);
04531 if (status == 0) {
04532 pvm_perror("pvm_spawn");
04533 pvm_exit();
04534 free(pvm_tid);
04535 free(pvmc);
04536 return 0;
04537 }
04538
04539 for (i = 0; i < pvm_n_task; i++) {
04540 pvmc[i].tid = pvm_tid[i];
04541 pvmc[i].wp = 0;
04542 pvmc[i].n_events = 0;
04543 pvmc[i].time = 0;
04544 dtid = pvm_tidtohost(pvm_tid[i]);
04545 for (j = 0; j < n_host; j++)
04546 if (dtid == hostp[j].hi_tid)
04547 strcpy(pvmc[i].host, hostp[j].hi_name);
04548 }
04549
04550 PVM_DEBUG("Spawing on hosts:");
04551 for (i = 0; i < pvm_n_task; i++)
04552 PVM_DEBUG("%s", pvmc[i].host);
04553
04554 if (status < pvm_n_task) {
04555 printf("Trouble spawning slaves. Aborting. Error codes are:\n");
04556 for (i = 0; i < pvm_n_task; i++)
04557 printf("TID %d %d\n", i, pvm_tid[i]);
04558
04559 pvm_exit();
04560 free(pvm_tid);
04561 free(pvmc);
04562 return 0;
04563 }
04564
04565
04566 for (i = 0; i < pvm_n_task; i++) {
04567 pvm_initsend(PvmDataDefault);
04568
04569 pvm_pkint(&i, 1, 1);
04570
04571 PVM_DEBUG("pvm_main: send index to client %d", i);
04572
04573 status = pvm_send(pvmc[i].tid, TAG_INIT);
04574 if (status < 0) {
04575 pvm_perror("pvm_send");
04576 return 0;
04577 }
04578 }
04579
04580 free(pvm_tid);
04581 } else {
04582 char path[256];
04583
04584 pvm_master = FALSE;
04585 pvm_slave = TRUE;
04586
04587
04588 strcpy(path, argv[0]);
04589 for (i = strlen(path); i > 0 && path[i] != DIR_SEPARATOR; i--)
04590 path[i] = 0;
04591 if (i > 0)
04592 path[i] = 0;
04593
04594 chdir(path);
04595 PVM_DEBUG("PATH=%s", path);
04596
04597
04598 timeout.tv_sec = 10;
04599 timeout.tv_usec = 0;
04600
04601 bufid = pvm_trecv(-1, -1, &timeout);
04602 if (bufid < 0) {
04603 pvm_perror("pvm_recv");
04604 return 0;
04605 }
04606 if (bufid == 0) {
04607 PVM_DEBUG("pvm_main: timeout receiving index, aborting analyzer.\n");
04608 return 0;
04609 }
04610
04611 status = pvm_upkint(&pvm_client_index, 1, 1);
04612 if (status < 0) {
04613 pvm_perror("pvm_upkint");
04614 return 0;
04615 }
04616
04617 PVM_DEBUG("Received client ID %d", pvm_client_index);
04618 }
04619
04620 return SUCCESS;
04621 }
04622
04623
04624
04625 int pvm_send_event(int index, EVENT_HEADER * pevent)
04626 {
04627 struct timeval timeout;
04628 int bufid, len, tag, tid, status;
04629
04630 if (pevent->data_size + sizeof(EVENT_HEADER) >= PVM_BUFFER_SIZE) {
04631 printf("Event too large (%d) for PVM buffer (%d), analyzer aborted\n",
04632 pevent->data_size + sizeof(EVENT_HEADER), PVM_BUFFER_SIZE);
04633 return RPC_SHUTDOWN;
04634 }
04635
04636
04637 timeout.tv_sec = 60;
04638 timeout.tv_usec = 0;
04639
04640 bufid = pvm_trecv(pvmc[index].tid, -1, &timeout);
04641 if (bufid < 0) {
04642 pvm_perror("pvm_recv");
04643 return RPC_SHUTDOWN;
04644 }
04645 if (bufid == 0) {
04646 printf("Timeout receiving data requests from %s, aborting analyzer.\n",
04647 pvmc[index].host);
04648 return RPC_SHUTDOWN;
04649 }
04650
04651 status = pvm_bufinfo(bufid, &len, &tag, &tid);
04652 if (status < 0) {
04653 pvm_perror("pvm_bufinfo");
04654 return RPC_SHUTDOWN;
04655 }
04656
04657 PVM_DEBUG("pvm_send_event: received request from client %d", index);
04658
04659
04660 pvm_initsend(PvmDataInPlace);
04661
04662 pvm_pkbyte((char *) pevent, pevent->data_size + sizeof(EVENT_HEADER), 1);
04663
04664 PVM_DEBUG("pvm_send_event: send events to client %d", index);
04665
04666 status = pvm_send(tid, TAG_DATA);
04667 if (status < 0) {
04668 pvm_perror("pvm_send");
04669 return RPC_SHUTDOWN;
04670 }
04671
04672 pvmc[index].time = ss_millitime();
04673
04674 return SUCCESS;
04675 }
04676
04677
04678
04679 int pvm_send_buffer(int index)
04680 {
04681 struct timeval timeout;
04682 int i, bufid, len, tag, tid, status;
04683
04684 PVM_DEBUG("pvm_send_buffer: index %d", index);
04685
04686 if (index == -2) {
04687 bufid = pvm_nrecv(-1, -1);
04688 } else {
04689
04690 timeout.tv_sec = 60;
04691 timeout.tv_usec = 0;
04692
04693 bufid = pvm_trecv(-1, -1, &timeout);
04694 }
04695
04696 if (bufid < 0) {
04697 pvm_perror("pvm_recv");
04698 return RPC_SHUTDOWN;
04699 }
04700 if (bufid == 0) {
04701 if (index == -2)
04702 return SUCCESS;
04703
04704 printf("Timeout receiving data requests, aborting analyzer.\n");
04705 return RPC_SHUTDOWN;
04706 }
04707
04708 status = pvm_bufinfo(bufid, &len, &tag, &tid);
04709 if (status < 0) {
04710 pvm_perror("pvm_bufinfo");
04711 return RPC_SHUTDOWN;
04712 }
04713
04714
04715 for (i = 0; i < pvm_n_task; i++)
04716 if (pvmc[i].tid == tid)
04717 break;
04718
04719 if (i == pvm_n_task) {
04720 cm_msg(MERROR, "pvm_send_buffer", "received message from unknown client %d", tid);
04721 return RPC_SHUTDOWN;
04722 }
04723
04724 PVM_DEBUG("pvm_send_buffer: received request from client %d", i);
04725
04726
04727 pvm_initsend(PvmDataInPlace);
04728
04729 pvm_pkbyte((char *) pvmc[i].buffer, pvmc[i].wp, 1);
04730
04731 PVM_DEBUG("pvm_send_buffer: send %d events (%1.1lfkB) to client %d",
04732 pvmc[i].n_events, pvmc[i].wp / 1024.0, i);
04733
04734 status = pvm_send(tid, TAG_DATA);
04735 if (status < 0) {
04736 pvm_perror("pvm_send");
04737 return RPC_SHUTDOWN;
04738 }
04739
04740 pvmc[i].wp = 0;
04741 pvmc[i].n_events = 0;
04742 pvmc[i].time = ss_millitime();
04743
04744
04745 if (index >= 0 && index != i)
04746 return pvm_send_buffer(index);
04747
04748 return SUCCESS;
04749 }
04750
04751
04752
04753 int pvm_distribute(ANALYZE_REQUEST * par, EVENT_HEADER * pevent)
04754 {
04755 char str[256];
04756 int i, index, size, status, min, max;
04757
04758 if (par == NULL && pevent->event_id == EVENTID_BOR) {
04759
04760 for (i = 0; i < pvm_n_task; i++) {
04761 status = pvm_send_event(i, pevent);
04762 if (status != SUCCESS)
04763 return status;
04764 }
04765
04766 return SUCCESS;
04767 }
04768
04769 size = sizeof(EVENT_HEADER) + pevent->data_size;
04770
04771 if (par == NULL || (par->ar_info.sampling_type & GET_FARM) == 0) {
04772
04773 for (i = 0; i < pvm_n_task; i++) {
04774
04775 if (pvmc[i].wp + size >= clp.pvm_buf_size) {
04776 status = pvm_send_buffer(i);
04777 if (status != SUCCESS)
04778 return status;
04779 }
04780
04781 if (size >= PVM_BUFFER_SIZE) {
04782 printf("Event too large (%d) for PVM buffer (%d), analyzer aborted\n", size,
04783 PVM_BUFFER_SIZE);
04784 return RPC_SHUTDOWN;
04785 }
04786
04787 memcpy(pvmc[i].buffer + pvmc[i].wp, pevent, size);
04788 pvmc[i].wp += size;
04789 pvmc[i].n_events++;
04790 }
04791 } else {
04792
04793 min = PVM_BUFFER_SIZE;
04794 index = 0;
04795 for (i = 0; i < pvm_n_task; i++)
04796 if (pvmc[i].wp < min) {
04797 min = pvmc[i].wp;
04798 index = i;
04799 }
04800
04801
04802 if (pvmc[index].wp + size >= clp.pvm_buf_size) {
04803 status = pvm_send_buffer(index);
04804 if (status != SUCCESS)
04805 return status;
04806 }
04807
04808 if (pvmc[index].wp + size >= PVM_BUFFER_SIZE) {
04809 printf("Event too large (%d) for PVM buffer (%d), analyzer aborted\n", size,
04810 PVM_BUFFER_SIZE);
04811 return RPC_SHUTDOWN;
04812 }
04813
04814
04815 memcpy(pvmc[index].buffer + pvmc[index].wp, pevent, size);
04816 pvmc[index].wp += size;
04817 pvmc[index].n_events++;
04818 }
04819
04820 sprintf(str, "%1.3lf: ", (ss_millitime() - pvm_start_time) / 1000.0);
04821 for (i = 0; i < pvm_n_task; i++)
04822 if (i == index)
04823 sprintf(str + strlen(str), "#%d# ", pvmc[i].wp);
04824 else
04825 sprintf(str + strlen(str), "%d ", pvmc[i].wp);
04826
04827
04828
04829 min = PVM_BUFFER_SIZE;
04830 max = 0;
04831 for (i = 0; i < pvm_n_task; i++) {
04832 if (pvmc[i].wp > max)
04833 max = pvmc[i].wp;
04834 if (pvmc[i].wp < min)
04835 min = pvmc[i].wp;
04836 }
04837
04838
04839 if (max < clp.pvm_buf_size / 2)
04840 return SUCCESS;
04841
04842
04843 if (min > clp.pvm_buf_size / 2) {
04844 status = pvm_send_buffer(-1);
04845 return status;
04846 }
04847
04848
04849 status = pvm_send_buffer(-2);
04850
04851 return status;
04852 }
04853
04854
04855
04856 int pvm_eor(int eor_tag)
04857 {
04858 struct timeval timeout;
04859 int bufid, len, tag, tid, i, j, status, size;
04860 ANA_TEST *tst_buf;
04861 DWORD count;
04862 char str[256];
04863
04864 printf("\n");
04865
04866 for (i = 0; i < pvm_n_task; i++)
04867 pvmc[i].eor_sent = FALSE;
04868
04869 do {
04870
04871 timeout.tv_sec = 60;
04872 timeout.tv_usec = 0;
04873
04874 bufid = pvm_trecv(-1, -1, &timeout);
04875 if (bufid < 0) {
04876 pvm_perror("pvm_recv");
04877 return RPC_SHUTDOWN;
04878 }
04879 if (bufid == 0) {
04880 printf("Timeout receiving data request, aborting analyzer.\n");
04881 return RPC_SHUTDOWN;
04882 }
04883
04884 status = pvm_bufinfo(bufid, &len, &tag, &tid);
04885 if (status < 0) {
04886 pvm_perror("pvm_bufinfo");
04887 return RPC_SHUTDOWN;
04888 }
04889
04890
04891 for (j = 0; j < pvm_n_task; j++)
04892 if (pvmc[j].tid == tid)
04893 break;
04894
04895 if (j == pvm_n_task) {
04896 cm_msg(MERROR, "pvm_eor", "received message from unknown client %d", tid);
04897 return RPC_SHUTDOWN;
04898 }
04899
04900 PVM_DEBUG("pvm_eor: received request from client %d", j);
04901
04902
04903 if (eor_tag == TAG_EOR && pvmc[j].wp > 0) {
04904 pvm_initsend(PvmDataInPlace);
04905
04906 pvm_pkbyte((char *) pvmc[j].buffer, pvmc[j].wp, 1);
04907
04908 PVM_DEBUG("pvm_eor: send %d events (%1.1lfkB) to client %d",
04909 pvmc[j].n_events, pvmc[j].wp / 1024.0, j);
04910
04911 status = pvm_send(tid, TAG_DATA);
04912 if (status < 0) {
04913 pvm_perror("pvm_send");
04914 return RPC_SHUTDOWN;
04915 }
04916
04917 pvmc[j].wp = 0;
04918 pvmc[j].n_events = 0;
04919 pvmc[j].time = ss_millitime();
04920 } else {
04921
04922 pvm_initsend(PvmDataDefault);
04923
04924 if (eor_tag == TAG_EOR)
04925 PVM_DEBUG("pvm_eor: send EOR to client %d", j);
04926 else
04927 PVM_DEBUG("pvm_eor: send EXIT to client %d", j);
04928
04929 printf("Shutting down %s \r", pvmc[j].host);
04930 fflush(stdout);
04931
04932 status = pvm_send(tid, eor_tag);
04933 if (status < 0) {
04934 pvm_perror("pvm_send");
04935 return RPC_SHUTDOWN;
04936 }
04937
04938 pvmc[j].eor_sent = TRUE;
04939
04940
04941 timeout.tv_sec = 60;
04942 timeout.tv_usec = 0;
04943
04944 bufid = pvm_trecv(tid, -1, &timeout);
04945 if (bufid < 0) {
04946 pvm_perror("pvm_recv");
04947 return RPC_SHUTDOWN;
04948 }
04949 if (bufid == 0) {
04950 printf("Timeout receiving EOR request, aborting analyzer.\n");
04951 return RPC_SHUTDOWN;
04952 }
04953
04954 status = pvm_bufinfo(bufid, &len, &tag, &tid);
04955 if (status < 0) {
04956 pvm_perror("pvm_bufinfo");
04957 return RPC_SHUTDOWN;
04958 }
04959
04960 PVM_DEBUG("\nGot %d bytes", len);
04961
04962 tst_buf = malloc(len);
04963 pvm_upkbyte((char *) tst_buf, len, 1);
04964
04965
04966 for (i = 0; i < (int) (len / sizeof(ANA_TEST)); i++) {
04967 sprintf(str, "/%s/Tests/%s", analyzer_name, tst_buf[i].name);
04968 count = 0;
04969 size = sizeof(DWORD);
04970 db_get_value(hDB, 0, str, &count, &size, TID_DWORD, TRUE);
04971 count += tst_buf[i].count;
04972
04973 db_set_value(hDB, 0, str, &count, sizeof(DWORD), 1, TID_DWORD);
04974 }
04975
04976 free(tst_buf);
04977 }
04978
04979
04980 for (j = 0; j < pvm_n_task; j++)
04981 if (!pvmc[j].eor_sent)
04982 break;
04983
04984 } while (j < pvm_n_task);
04985
04986 printf("\n");
04987
04988 return SUCCESS;
04989 }
04990
04991
04992
04993 int pvm_merge()
04994 {
04995 int i, j;
04996 char fn[10][8], str[256], file_name[256], error[256];
04997 char ext[10], *p;
04998
04999 strcpy(str, out_info.filename);
05000 if (strchr(str, '%') != NULL)
05001 sprintf(file_name, str, current_run_number);
05002 else
05003 strcpy(file_name, str);
05004
05005
05006 out_gzip = FALSE;
05007 ext[0] = 0;
05008 if (strchr(file_name, '.')) {
05009 p = file_name + strlen(file_name) - 1;
05010 while (*p != '.')
05011 p--;
05012 strcpy(ext, p);
05013 }
05014 if (strncmp(ext, ".gz", 3) == 0) {
05015 out_gzip = TRUE;
05016 *p = 0;
05017 p--;
05018 while (*p != '.' && p > file_name)
05019 p--;
05020 strcpy(ext, p);
05021 }
05022
05023 if (strncmp(ext, ".asc", 4) == 0)
05024 out_format = FORMAT_ASCII;
05025 else if (strncmp(ext, ".mid", 4) == 0)
05026 out_format = FORMAT_MIDAS;
05027 else if (strncmp(ext, ".rz", 3) == 0)
05028 out_format = FORMAT_HBOOK;
05029 else {
05030 strcpy(error,
05031 "Unknown output data format. Please use file extension .asc, .mid or .rz.\n");
05032 cm_msg(MERROR, "pvm_merge", error);
05033 return 0;
05034 }
05035
05036 if (out_format == FORMAT_HBOOK) {
05037 if (pvm_n_task <= 10) {
05038 for (i = 0; i < pvm_n_task; i++)
05039 sprintf(fn[i], "n%d.rz", i);
05040
05041 HMERGE(pvm_n_task, fn, file_name);
05042 } else {
05043 for (i = 0; i <= pvm_n_task / 10; i++) {
05044 for (j = 0; j < 10 && j + i * 10 < pvm_n_task; j++)
05045 sprintf(fn[j], "n%d.rz", j + i * 10);
05046
05047 sprintf(str, "t%d.rz", i);
05048 printf("Merging %d files to %s:\n", j, str);
05049 HMERGE(j, fn, str);
05050 }
05051 for (i = 0; i <= pvm_n_task / 10; i++)
05052 sprintf(fn[i], "t%d.rz", i);
05053
05054 printf("Merging %d files to %s:\n", i, file_name);
05055 HMERGE(i, fn, file_name);
05056 }
05057 }
05058
05059 return SUCCESS;
05060 }
05061
05062 #endif
05063
05064
05065
05066 #ifdef USE_ROOT
05067
05068
05069
05070 #if defined ( OS_UNIX )
05071 #define THREADRETURN
05072 #define THREADTYPE void
05073 #endif
05074 #if defined( OS_WINNT )
05075 #define THREADRETURN 0
05076 #define THREADTYPE DWORD WINAPI
05077 #endif
05078
05079
05080
05081 TFolder *ReadFolderPointer(TSocket * fSocket)
05082 {
05083
05084 TMessage *m = 0;
05085 fSocket->Recv(m);
05086 POINTER_T p;
05087 *m >> p;
05088 return (TFolder *) p;
05089 }
05090
05091
05092
05093 THREADTYPE root_server_thread(void *arg)
05094
05095
05096
05097 {
05098 char request[256];
05099
05100 TSocket *sock = (TSocket *) arg;
05101
05102 do {
05103
05104
05105 if (sock->Recv(request, sizeof(request)) <= 0) {
05106
05107 sock->Close();
05108 delete sock;
05109 return THREADRETURN;
05110
05111 } else {
05112
05113 TMessage *message = new TMessage(kMESS_OBJECT);
05114
05115 if (strcmp(request, "GetListOfFolders") == 0) {
05116
05117 TFolder *folder = ReadFolderPointer(sock);
05118 if (folder == NULL) {
05119 message->Reset(kMESS_OBJECT);
05120 message->WriteObject(NULL);
05121 sock->Send(*message);
05122 delete message;
05123 continue;
05124 }
05125
05126 TObject *obj;
05127 TObjArray *names = new TObjArray(100);
05128
05129 TCollection *folders = folder->GetListOfFolders();
05130 TIterator *iterFolders = folders->MakeIterator();
05131 while ((obj = iterFolders->Next()) != NULL)
05132 names->Add(new TObjString(obj->GetName()));
05133
05134
05135 message->Reset(kMESS_OBJECT);
05136 message->WriteObject(names);
05137 sock->Send(*message);
05138
05139 for (int i = 0; i < names->GetLast() + 1; i++)
05140 delete(TObjString *) names->At(i);
05141
05142 delete names;
05143
05144 delete message;
05145
05146 } else if (strncmp(request, "FindObject", 10) == 0) {
05147
05148 TFolder *folder = ReadFolderPointer(sock);
05149
05150
05151 TObject *obj;
05152 if (strncmp(request + 10, "Any", 3) == 0)
05153 obj = folder->FindObjectAny(request + 14);
05154 else
05155 obj = folder->FindObject(request + 11);
05156
05157
05158 if (!obj)
05159 sock->Send("Error");
05160 else {
05161 message->Reset(kMESS_OBJECT);
05162 message->WriteObject(obj);
05163 sock->Send(*message);
05164 }
05165 delete message;
05166
05167 } else if (strncmp(request, "FindFullPathName", 16) == 0) {
05168
05169 TFolder *folder = ReadFolderPointer(sock);
05170
05171
05172 const char *path = folder->FindFullPathName(request + 17);
05173
05174
05175 if (!path) {
05176 sock->Send("Error");
05177 } else {
05178 TObjString *obj = new TObjString(path);
05179 message->Reset(kMESS_OBJECT);
05180 message->WriteObject(obj);
05181 sock->Send(*message);
05182 delete obj;
05183 }
05184 delete message;
05185
05186 } else if (strncmp(request, "Occurence", 9) == 0) {
05187
05188 TFolder *folder = ReadFolderPointer(sock);
05189
05190
05191 TMessage *m = 0;
05192 sock->Recv(m);
05193 TObject *obj = ((TObject *) m->ReadObject(m->GetClass()));
05194
05195
05196 Int_t retValue = folder->Occurence(obj);
05197
05198
05199 message->Reset(kMESS_OBJECT);
05200 *message << retValue;
05201 sock->Send(*message);
05202
05203 delete message;
05204
05205 } else if (strncmp(request, "GetPointer", 10) == 0) {
05206
05207
05208 TObject *obj = gROOT->FindObjectAny(request + 11);
05209
05210
05211 message->Reset(kMESS_ANY);
05212 POINTER_T p = (POINTER_T) obj;
05213 *message << p;
05214 sock->Send(*message);
05215
05216 delete message;
05217
05218 } else if (strncmp(request, "Command", 7) == 0) {
05219 char objName[100], method[100];
05220 sock->Recv(objName, sizeof(objName));
05221 sock->Recv(method, sizeof(method));
05222 TObject *object = gROOT->FindObjectAny(objName);
05223 if (object && object->InheritsFrom(TH1::Class())
05224 && strcmp(method, "Reset") == 0)
05225 static_cast < TH1 * >(object)->Reset();
05226
05227 } else if (strncmp(request, "SetCut", 6) == 0) {
05228
05229
05230 char name[256];
05231 sock->Recv(name, sizeof(name));
05232 TCutG *cut = (TCutG *) gManaHistosFolder->FindObjectAny(name);
05233
05234 TMessage *m = 0;
05235 sock->Recv(m);
05236 TCutG *newc = ((TCutG *) m->ReadObject(m->GetClass()));
05237
05238 if (cut) {
05239 cm_msg(MINFO, "root server thread", "changing cut %s", newc->GetName());
05240 newc->TAttMarker::Copy(*cut);
05241 newc->TAttFill::Copy(*cut);
05242 newc->TAttLine::Copy(*cut);
05243 newc->TNamed::Copy(*cut);
05244 cut->Set(newc->GetN());
05245 for (int i = 0; i < cut->GetN(); ++i) {
05246 cut->SetPoint(i, newc->GetX()[i], newc->GetY()[i]);
05247 }
05248 } else {
05249 cm_msg(MERROR, "root server thread", "ignoring receipt of unknown cut %s",
05250 newc->GetName());
05251 }
05252 delete newc;
05253
05254 } else
05255 printf("SocketServer: Received unknown command \"%s\"\n", request);
05256 }
05257 } while (1);
05258
05259 return THREADRETURN;
05260 }
05261
05262
05263
05264 THREADTYPE root_socket_server(void *arg)
05265 {
05266
05267
05268 int port;
05269
05270 port = *(int *) arg;
05271
05272 printf("Root server listening on port %d...\n", port);
05273 TServerSocket *lsock = new TServerSocket(port, kTRUE);
05274
05275 do {
05276 TSocket *sock = lsock->Accept();
05277
05278
05279
05280 #if defined ( __linux__ )
05281 TThread *thread = new TThread("Server", root_server_thread, sock);
05282 thread->Run();
05283 #endif
05284 #if defined( _MSC_VER )
05285 LPDWORD lpThreadId = 0;
05286 CloseHandle(CreateThread(NULL, 1024, &root_server_thread, sock, 0, lpThreadId));
05287 #endif
05288 } while (1);
05289
05290 return THREADRETURN;
05291 }
05292
05293
05294
05295 void start_root_socket_server(int port)
05296 {
05297 static int pport = port;
05298 #if defined ( __linux__ )
05299 TThread *thread = new TThread("server_loop", root_socket_server, &pport);
05300 thread->Run();
05301 #endif
05302 #if defined( _MSC_VER )
05303 LPDWORD lpThreadId = 0;
05304 CloseHandle(CreateThread(NULL, 1024, &root_socket_server, &pport, 0, lpThreadId));
05305 #endif
05306 }
05307
05308
05309
05310 void *root_event_loop(void *arg)
05311
05312
05313
05314 {
05315 if (clp.online)
05316 loop_online();
05317 else
05318 loop_runs_offline();
05319
05320 gSystem->ExitLoop();
05321
05322 return NULL;
05323 }
05324
05325 #endif
05326
05327
05328
05329 int main(int argc, char *argv[])
05330 {
05331 INT status, size;
05332 char str[256];
05333 HNDLE hkey;
05334
05335 #ifdef HAVE_PVM
05336 int i;
05337
05338 str[0] = 0;
05339 for (i = 0; i < argc; i++) {
05340 strcat(str, argv[i]);
05341 strcat(str, " ");
05342 }
05343 PVM_DEBUG("Analyzer started: %s", str);
05344 #endif
05345
05346 #ifdef USE_ROOT
05347 int argn = 1;
05348 char *argp = (char *) argv[0];
05349
05350 manaApp = new TRint("ranalyzer", &argn, &argp, NULL, 0, true);
05351
05352
05353 clp.root_port = 9090;
05354 #endif
05355
05356
05357 cm_get_environment(clp.host_name, sizeof(clp.host_name), clp.exp_name,
05358 sizeof(clp.exp_name));
05359
05360 #ifdef HAVE_HBOOK
05361
05362 clp.lrec = HBOOK_LREC;
05363 #endif
05364
05365
05366 status = getparam(argc, argv);
05367 if (status != CM_SUCCESS)
05368 return 1;
05369
05370
05371 if (clp.daemon) {
05372 printf("Becoming a daemon...\n");
05373 clp.quiet = TRUE;
05374 ss_daemon_init(FALSE);
05375 }
05376
05377
05378 if (clp.pvm_buf_size == 0)
05379 clp.pvm_buf_size = 512 * 1024;
05380 else
05381 clp.pvm_buf_size *= 1024;
05382 if (clp.pvm_buf_size > PVM_BUFFER_SIZE) {
05383 printf("Buffer size cannot be larger than %dkB\n", PVM_BUFFER_SIZE / 1024);
05384 return 1;
05385 }
05386
05387
05388 clp.online = (clp.input_file_name[0][0] == 0);
05389
05390 #ifdef HAVE_HBOOK
05391
05392 if (clp.online || equal_ustring(clp.output_file_name, "OFLN"))
05393 clp.rwnt = TRUE;
05394 #endif
05395
05396 #ifdef HAVE_PVM
05397 status = pvm_main(argv);
05398 if (status != CM_SUCCESS)
05399 return 1;
05400 #endif
05401
05402 #ifdef USE_ROOT
05403
05404 ss_force_single_thread();
05405 #endif
05406
05407
05408 if (clp.online) {
05409 if (clp.host_name[0])
05410 printf("Connect to experiment %s on host %s...", clp.exp_name, clp.host_name);
05411 else
05412 printf("Connect to experiment %s...", clp.exp_name);
05413 }
05414
05415 status =
05416 cm_connect_experiment1(clp.host_name, clp.exp_name, analyzer_name, NULL, odb_size,
05417 DEFAULT_WATCHDOG_TIMEOUT);
05418
05419 if (status == CM_UNDEF_EXP) {
05420 printf("\nError: Experiment \"%s\" not defined.\n", clp.exp_name);
05421 if (getenv("MIDAS_DIR")) {
05422 printf
05423 ("Note that \"MIDAS_DIR\" is defined, which results in a single experiment\n");
05424 printf
05425 ("called \"Default\". If you want to use the \"exptab\" file, undefine \"MIDAS_DIR\".\n");
05426 }
05427 return 1;
05428 } else if (status != CM_SUCCESS) {
05429 cm_get_error(status, str);
05430 printf("\nError: %s\n", str);
05431 return 1;
05432 }
05433
05434 if (clp.online)
05435 printf("OK\n");
05436
05437
05438 cm_get_experiment_database(&hDB, NULL);
05439 db_set_value(hDB, 0, "/Runinfo/Online Mode", &clp.online, sizeof(clp.online), 1,
05440 TID_INT);
05441
05442 if (clp.online) {
05443
05444 status = cm_exist(analyzer_name, FALSE);
05445 if (status == CM_SUCCESS) {
05446 cm_disconnect_experiment();
05447 printf("An analyzer named \"%s\" is already running in this experiment.\n",
05448 analyzer_name);
05449 printf
05450 ("Please select another analyzer name in analyzer.c or stop other analyzer.\n");
05451 return 1;
05452 }
05453
05454
05455 if (cm_register_transition(TR_START, tr_start, 300) != CM_SUCCESS ||
05456 cm_register_transition(TR_STOP, tr_stop, 700) != CM_SUCCESS ||
05457 cm_register_transition(TR_PAUSE, tr_pause, 700) != CM_SUCCESS ||
05458 cm_register_transition(TR_RESUME, tr_resume, 300) != CM_SUCCESS) {
05459 printf("Failed to start local RPC server");
05460 return 1;
05461 }
05462 } else {
05463 if (!pvm_slave) {
05464 status = cm_exist(analyzer_name, FALSE);
05465 if (status == CM_SUCCESS) {
05466
05467 cm_cleanup(analyzer_name, FALSE);
05468
05469 status = cm_exist(analyzer_name, FALSE);
05470 if (status == CM_SUCCESS) {
05471
05472 status = cm_shutdown(analyzer_name, FALSE);
05473 if (status == CM_SHUTDOWN)
05474 printf("Previous analyzer stopped\n");
05475 }
05476 }
05477 }
05478 }
05479
05480 #ifdef HAVE_HBOOK
05481
05482 cm_register_function(RPC_ANA_CLEAR_HISTOS, ana_callback);
05483 #endif
05484
05485
05486 cm_set_watchdog_params(TRUE, DEFAULT_RPC_TIMEOUT);
05487
05488
05489 if (!clp.online)
05490 cm_set_watchdog_params(TRUE, 2000);
05491
05492
05493 if (clp.debug)
05494 cm_set_watchdog_params(0, 0);
05495
05496
05497 if (init_module_parameters(FALSE) != CM_SUCCESS) {
05498 cm_disconnect_experiment();
05499 return 1;
05500 }
05501
05502
05503 sprintf(str, "/%s/Output", analyzer_name);
05504 db_check_record(hDB, 0, str, ANA_OUTPUT_INFO_STR, TRUE);
05505 db_find_key(hDB, 0, str, &hkey);
05506 assert(hkey);
05507 size = sizeof(out_info);
05508 db_get_record(hDB, hkey, &out_info, &size, 0);
05509
05510 #ifdef USE_ROOT
05511
05512 gManaHistosFolder =
05513 gROOT->GetRootFolder()->AddFolder("histos", "MIDAS Analyzer Histograms");
05514 gHistoFolderStack = new TObjArray();
05515 gROOT->GetListOfBrowsables()->Add(gManaHistosFolder, "histos");
05516
05517
05518 if (strstr(out_info.last_histo_filename, ".rz"))
05519 strcpy(out_info.last_histo_filename, "last.root");
05520
05521 if (strstr(out_info.histo_dump_filename, ".rz"))
05522 strcpy(out_info.histo_dump_filename, "his%05d.root");
05523
05524 db_set_record(hDB, hkey, &out_info, sizeof(out_info), 0);
05525
05526
05527 if (clp.root_port)
05528 start_root_socket_server(clp.root_port);
05529
05530 #endif
05531
05532 #ifdef HAVE_HBOOK
05533
05534 if (strstr(out_info.last_histo_filename, ".root"))
05535 strcpy(out_info.last_histo_filename, "last.rz");
05536
05537 if (strstr(out_info.histo_dump_filename, ".root"))
05538 strcpy(out_info.histo_dump_filename, "his%05d.rz");
05539
05540 db_set_record(hDB, hkey, &out_info, sizeof(out_info), 0);
05541 #endif
05542
05543 #ifdef HAVE_HBOOK
05544
05545 if (clp.online) {
05546 HLIMAP(pawc_size / 4, out_info.global_memory_name);
05547 printf("\nGLOBAL MEMORY NAME = %s\n", out_info.global_memory_name);
05548 } else {
05549 if (equal_ustring(clp.output_file_name, "OFLN")) {
05550 strcpy(str, "OFLN");
05551 HLIMAP(pawc_size / 4, str);
05552 printf("\nGLOBAL MEMORY NAME = %s\n", "OFLN");
05553 } else
05554 HLIMIT(pawc_size / 4);
05555 }
05556 #endif
05557
05558
05559 if (mana_init() != CM_SUCCESS) {
05560 cm_disconnect_experiment();
05561 return 1;
05562 }
05563
05564
05565 if (clp.online)
05566 load_last_histos();
05567
05568
05569 register_requests();
05570
05571
05572 if (!clp.quiet && !pvm_slave)
05573 ss_getchar(0);
05574
05575
05576
05577 if (clp.online)
05578 loop_online();
05579 else
05580 loop_runs_offline();
05581
05582
05583 if (!clp.quiet && !pvm_slave)
05584 ss_getchar(TRUE);
05585
05586
05587 mana_exit();
05588
05589
05590 if (clp.online)
05591 save_last_histos();
05592
05593 #ifdef HAVE_PVM
05594
05595 PVM_DEBUG("Analyzer stopped");
05596
05597
05598 pvm_exit();
05599
05600
05601 if (pvm_slave)
05602 disable_shm_write = TRUE;
05603
05604 #endif
05605
05606
05607 cm_disconnect_experiment();
05608
05609 #ifdef USE_ROOT
05610 if (clp.start_rint)
05611 manaApp->Run(true);
05612 printf("\r \n");
05613 #endif
05614
05615 return 0;
05616 }
05617
05618 #ifdef LINK_TEST
05619 int odb_size;
05620 char* analyzer_name;
05621 int analyzer_loop_period;
05622 ANALYZE_REQUEST analyze_request[1];
05623 int analyzer_init(void) { return 0; }
05624 int analyzer_loop(void) { return 0; }
05625 int analyzer_exit(void) { return 0; }
05626 int ana_end_of_run(INT run_number, char *error) { return 0; }
05627 int ana_begin_of_run(INT run_number, char *error) { return 0; }
05628 int ana_resume_run(INT run_number, char *error) { return 0; }
05629 int ana_pause_run(INT run_number, char *error) { return 0; }
05630 #endif