StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
gl3Conductor.cxx
1 //:>------------------------------------------------------------------
2 //: FILE: gl3Conductor.cc
3 //: HISTORY:
4 //: 1 feb 2000 version 1.00
5 //: 6 jul 2000 add St_l3_Coordinate_Transformer
6 //: 27 jul 2000 add print timing
7 //:<------------------------------------------------------------------
8 #include "Stl3Util/gl3/gl3Conductor.h"
9 
10 #include "Stl3Util/base/L3swap.h"
11 #include "Stl3Util/base/realcc.h"
12 #include "Stl3Util/base/FtfLog.h"
13 
14 #include <time.h>
15 #include <errno.h>
16 #include <netinet/in.h>
17 #include <unistd.h>
18 
19 #ifdef GL3ONLINE
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <fcntl.h>
23 #endif
24 
25 //VP extern int errno;
26 
27 
28 //####################################################################
29 //
30 //####################################################################
31 gl3Conductor::gl3Conductor (void){
32  unsigned int start = realcc();
33  sleep(1);
34  unsigned int stop = realcc();
35 
36 
37  ccPerMs = (double)(stop-start)/1000.;
38 
39  //ftfLog("gl3Conductor: estimated CPU freq: %7.3f MHz\n", ccPerMs/1000.);
40 
41  nAlgorithms = 0;
42 }
43 
44 //####################################################################
45 //
46 //####################################################################
47 gl3Conductor::~gl3Conductor ( ) {
48 
49  if ( event != NULL ) delete[] event ;
50  clearAlgorithms();
51  if ( algorithm != NULL ) delete algorithm;
52  if ( summary != NULL ) delete[] summary ;
53  if ( summaryData != NULL ) free (summaryData) ;
54  delete []tokenIndex ;
55 }
56 
57 //####################################################################
58 //
59 //####################################################################
60 int gl3Conductor::configure (L3_CFG *cfg)
61 {
62  clearAlgorithms();
63 
64  if(cfg == NULL || cfg == (L3_CFG *)-1) {
65  ftfLog("gl3Conductor::configure: No configuration information found.\n");
66  return 1;
67  }
68 
69  L3_ALGORITHMS *algos = cfg->l3_setup.gl3_algorithms;
70 
71  for (int i=0; i<GL3_ALG_MAX_NUM; i++) {
72  if(ntohl(algos[i].alg_id) != 0) {
73  gl3Algorithm *algo =
74  gl3InstantiateAlgorithm(ntohl(algos[i].alg_id));
75 
76  if (algo == NULL) {
77  ftfLog("gl3Conductor::configure: Instantiation of algorithm #%d failed.\n", i);
78 
79  return 1;
80  }
81 
82  algo->setScaling(ntohl(algos[i].preScale),
83  ntohl(algos[i].postScale));
84 
85  if (algo->setParameters(ntohl(algos[i].GI1),
86  ntohl(algos[i].GI2),
87  ntohl(algos[i].GI3),
88  ntohl(algos[i].GI4),
89  ntohl(algos[i].GI5),
90  fswap(algos[i].GF1),
91  fswap(algos[i].GF2),
92  fswap(algos[i].GF3),
93  fswap(algos[i].GF4),
94  fswap(algos[i].GF5))) {
95  ftfLog("gl3Conductor::configure: Invalid parameters for algorithm %s (ID %d)", algo->getAlgorithmName(), algo->getAlgorithmID());
96  return 1;
97  }
98 
99 
100  if(add(algo) != 0) {
101  ftfLog("gl3Conductor::configure: Appending algorithm %s (ID %i) to list failed.\n",
102  algo->getAlgorithmName(), algo->getAlgorithmID());
103  return 1;
104  }
105 
106  algo->showConfiguration();
107 
108  }
109  }
110 
111  //ftfLog("gl3Conductor::configure: Done.\n");
112  return 0;
113 }
114 
115 //####################################################################
116 //
117 //####################################################################
118 int gl3Conductor::add( gl3Algorithm* module ) {
119  if ( nAlgorithms >= maxAlgorithms ) {
120  ftfLog ( "gl3Conductor::add: Max. number of algorithms reached\n" ) ;
121  return 1;
122  }
123  algorithm[nAlgorithms] = module ;
124  nAlgorithms++ ;
125 
126  return 0 ;
127 }
128 
129 //####################################################################
130 //
131 //####################################################################
132 void gl3Conductor::clearAlgorithms()
133 {
134  for (int i =0; i<nAlgorithms; i++) {
135  if(algorithm[i]) {
136  delete algorithm[i];
137  algorithm[i] = NULL;
138  }
139  }
140 
141  nAlgorithms = 0;
142 }
143 
144 //####################################################################
145 //
146 //####################################################################
147 
148 int gl3Conductor::checkHistoRequest ( ) {
149 #ifdef GL3ONLINE
150  struct sockaddr_in remoteAddress; /* connector's address information */
151  socklen_t sin_size = sizeof(struct sockaddr_in);
152 
153  if ((remoteSocket = accept(socketFd, (struct sockaddr *)&remoteAddress,
154  &sin_size)) == -1) {
155  return 0;
156  }
157 
158  const int maxBytes = 100000 ;
159  char* buffer = new char[maxBytes];
160 
161  int nBytes = writeHistos ( maxBytes, buffer ) ;
162 
163  if ( nBytes < 0 ) {
164  ftfLog ( "gl3Conductor::checkHistoRequest: buffer too small \n " ) ;
165  return 1 ;
166  }
167  int nSend = send(remoteSocket, buffer, nBytes, 0 ) ;
168  ftfLog ( "gl3Conductor: %d out of %d bytes sent\n ", nSend, nBytes ) ;
169  if ( nSend == -1) {
170  perror("send");
171  return 1 ;
172  }
173  delete []buffer ;
174 #endif
175  return 0 ;
176 }
177 
178 //####################################################################
179 //
180 //####################################################################
181 int gl3Conductor::end ( ){
182 #ifdef GL3ONLINE
183  close ( socketFd ) ;
184 #endif
185  for ( int i = 0 ; i < nAlgorithms ; i++ ) {
186  algorithm[i]->end( );
187  }
188  return 0 ;
189 }
190 
191 
192 //####################################################################
193 //
194 //####################################################################
195 gl3Event* gl3Conductor::getEvent ( int token ) {
196 
197  int index = getTokenIndex(token) ;
198 
199  if (index < 0)
200  return NULL;
201  else
202  return &(event[index]) ;
203 }
204 
205 
206 //####################################################################
207 //
208 //####################################################################
209 int gl3Conductor::init ( ){
210 
211  ftfLog("gl3Conductor::init: %d algos\n", nAlgorithms);
212 
213 #ifdef GL3ONLINE
214  l3Rates = new gl3Histo("l3rates",
215  "L3 trigger rates",
216  nAlgorithms+2, -2.5, (double)nAlgorithms-0.5);
217 
218  histoList.push_back(l3Rates);
219 
220  allocateTimingHistos();
221 #endif
222 
223  for ( int i = 0 ; i < nAlgorithms ; i++ ) {
224  algorithm[i]->init();
225  }
226 
227  nReco = 0;
228  return 0 ;
229 }
230 
231 
232 //####################################################################
233 //
234 //####################################################################
235 
236 int gl3Conductor::processEvent(EventDescriptor *desc,
237  L3_P* l3data,
238  TrgSumData* trgSum,
239  RawTrgDet* trgRaw)
240 {
241  resetTimer();
242 
243  // If we get a EventDescriptor, it should be for the right token
244  if ( desc && desc->token != l3data->bh.token ) {
245  ftfLog ("gl3Conductor::readEvent: token mismatch (%d and %d)\n",
246  desc->token, l3data->bh.token);
247  return -1;
248  }
249 
250  int token = l3data->bh.token;
251 
252 
253 
254  if ( token < 0 || token > maxTokens ){
255  ftfLog ("gl3Conductor::readEvent: %d token out of bounds\n", token );
256  return -1;
257  }
258 
259  // Look for a free event container
260  int index = getFreeEventIndex();
261  if ( index < 0 ) {
262  ftfLog ( "gl3Conductor::readEvent: No free event container \n" ) ;
263  return -1;
264  }
265  tokenIndex[token] = index;
266 
267  // Read Event and check if errors occured
268 
269  if (event[index].readEventDescriptor(desc) != 0) {
270  ftfLog ( "gl3Conductor::processEvent: error reading EventDescriptor\n" ) ;
271  return -1;
272  }
273 
274 
275  if ( event[index].getTrgCmd() == 0 ||
276  event[index].getTrgCmd() == 1 ||
277  event[index].getTrgCmd() == 2 ||
278  event[index].getTrgCmd() == 3 ) {
279  ftfLog ("gl3Conductor::processEvent: Trigger Command 0,1,2 or 3 received\n");
280  return 2; // hard trigger
281  }
282 
283  if ( event[index].getTrgCmd() == 5 ||
284  event[index].getTrgCmd() == 6 ||
285  event[index].getTrgCmd() == 7 ) {
286  ftfLog ("gl3Conductor::processEvent: Trigger Command 5,6 or 7 received - unknown physics run type\n");
287  // continue reading data and running algorithms
288  }
289 
290  // Read L3 data
291  if ( event[index].readL3Data(l3data) != 0 ) {
292  ftfLog ( "gl3Conductor::processEvent: error reading L3 data\n" ) ;
293  return -1;
294  }
295 
296 
297  // Do not ontinue (run algorithms) if we have a laser or pulser event.
298  // Return decision = 1 to ensure the event is built.
299  if ( event[index].getTrgCmd() >= 8 ) {
300  // Laser trigger
301  return 2; // hard trigger
302  }
303 
304  timingMark(); // step 1
305 
306  if ( event[index].readTrgData(trgSum, trgRaw) != 0 ) {
307  ftfLog ( "gl3Conductor::processEvent: error reading TRG data\n" ) ;
308  return -1;
309  }
310 
311 
312  timingMark(); // step 2
313 
314  // The preparation is done, now let's run the algorithms.
315  int decision = 0;
316 
317  for ( int i = 0 ; i < nAlgorithms ; i++ ) {
318  int alg_decision = algorithm[i]->process( &(event[index]));
319  if (alg_decision > decision) {
320  decision = alg_decision;
321  }
322  timingMark(); // step 3...2+nAlgorithms
323  }
324 
325  // Now increment the counters for the algorithms. Can't be done
326  // earlier, because if an event crashes, we do not want to have
327  // any counters incremented
328  nReco++;
329  for ( int i = 0 ; i < nAlgorithms ; i++ ) {
330  algorithm[i]->incrementCounters();
331  }
332 
333  collectSummary(token);
334 
335  timingMark(); // step 4+nAlgorithms
336 
337  fillTimingHistos();
338 
339 #ifdef GL3ONLINE
340  l3Rates->Fill(-2); // event was processed
341  if (decision) {
342  l3Rates->Fill(-1); // event was triggered for any reason
343 
344  for (int i=0; i<nAlgorithms;i++) {
345 
346  if (summaryData[index].alg[i].accept)
347  l3Rates->Fill(i); // accepted because of algorithm #i
348 
349  // cout << "alg #" << i << ": "
350 // << summaryData[index].alg[i].accept
351 // << " histo: " << l3Rates->GetY(i+2)
352 // << endl;
353 
354 
355  }
356  }
357 
358  if ( communicationsFlag ) {
359  checkHistoRequest();
360  }
361 #endif
362 
363  if (nAlgorithms == 0) decision=1; // no algs -> trigger everything
364 
365  return decision ;
366 }
367 
368 
369 
370 
371 //####################################################################
372 // Copy the previously filled summary data to the requested locations
373 //####################################################################
374 int gl3Conductor::fillSummary(int token,
375  struct L3_summary* summaryDest,
376  struct L3_SUMD *summaryDataDest)
377 {
378  int index = getTokenIndex(token);
379  if (index < 0) return 1;
380 
381  memcpy(summaryDest, &summary[index], sizeof(L3_summary));
382 
383  memcpy(summaryDataDest, &summaryData[index],
384  summaryData[index].bh.length*4);
385 
386  return 0;
387 }
388 
389 //####################################################################
390 // Fill summary information for a given token
391 //####################################################################
392 int gl3Conductor::collectSummary(int token)
393 {
394  int index = tokenIndex[token];
395  if (index < 0) return 1;
396 
397  sprintf(summaryData->bh.bank_type, CHAR_L3_SUMD);
398  summaryData[index].bh.length =
399  (sizeof(L3_SUMD) + (nAlgorithms-1)*sizeof(algorithm_data))/4;
400  summaryData[index].bh.bank_id = 0;
401  summaryData[index].bh.format_ver = 0;
402  summaryData[index].bh.byte_order = DAQ_RAW_FORMAT_ORDER;
403  summaryData[index].bh.format_number = 0;
404  summaryData[index].bh.token = token;
405  summaryData[index].bh.w9 = DAQ_RAW_FORMAT_WORD9;
406  summaryData[index].bh.crc = 0;
407 
408  summaryData[index].nProcessed = 0;
409  summaryData[index].nReconstructed = nReco;
410  summaryData[index].nAlg = nAlgorithms;
411 
412  summary[index].accept = 0;
413  summary[index].build = 0;
414  summary[index].on = 0;
415 
416  for (int i = 0; i < nAlgorithms; i++) {
417  algorithm[i]->fillSummary(&summaryData[index].alg[i]);
418 
419  if(summaryData[index].alg[i].on)
420  summary[index].on |= 1<<i;
421 
422  if(summaryData[index].alg[i].accept)
423  summary[index].accept |= 1<<i;
424 
425  if(summaryData[index].alg[i].build)
426  summary[index].build |= 1<<i;
427 
428  }
429 
430  summary[index].nTracks = event[index].getNTracks();
431 
432  return 0;
433 }
434 
435 //####################################################################
436 //
437 //####################################################################
438 int gl3Conductor::releaseToken ( int token ) {
439  int index = getTokenIndex(token);
440  if (index < 0) return 1;
441 
442  event[index].resetEvent();
443  return 0;
444 }
445 //####################################################################
446 //
447 //####################################################################
448 int gl3Conductor::resetHistos ( ) {
449  list<gl3Histo*>::iterator histo;
450  for(histo=histoList.begin(); histo!=histoList.end(); histo++) {
451  (*histo)->Reset();
452 
453  }
454 
455  return 0 ;
456 }//####################################################################
457 //
458 //####################################################################
459 int gl3Conductor::runStart ( int _runNumber ) {
460  runNumber = _runNumber ;
461  for ( int i = 0 ; i < nAlgorithms ; i++ ) {
462  algorithm[i]->init();
463  }
464 
465  nReco = 0;
466  return resetHistos ( ) ;
467 }
468 //####################################################################
469 //
470 //####################################################################
471 int gl3Conductor::runEnd ( ) {
472  for ( int i = 0 ; i < nAlgorithms ; i++ ) {
473  algorithm[i]->end( );
474  }
475  return 0 ;
476 }
477 //####################################################################
478 //
479 //####################################################################
480 int gl3Conductor::setCommunications ( ){
481  //
482 #ifdef GL3ONLINE
483  struct sockaddr_in gl3Address; /* my address information */
484 
485  gl3Port = 3333 ;
486  int backLog = 5 ; // how many pending connections will hold
487 
488  if ((socketFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
489  ftfLog("setCommunications socket: %s",strerror(errno) );
490  return -1;
491  }
492  fcntl(socketFd, F_SETFL, O_NONBLOCK);
493 
494 
495  gl3Address.sin_family = AF_INET; /* host byte order */
496  gl3Address.sin_port = htons(gl3Port); /* short, network byte order */
497  gl3Address.sin_addr.s_addr = INADDR_ANY;/* automatically fill with my IP */
498  bzero(&(gl3Address.sin_zero), 8); /* zero the rest of the struct */
499 
500  if (bind(socketFd, (struct sockaddr *)&gl3Address,
501  sizeof(struct sockaddr)) == -1) {
502  ftfLog("setCommunications bind: %s",strerror(errno) );
503  return -1;
504  }
505 
506  if (listen(socketFd, backLog) == -1) {
507  ftfLog("setCommunications listen: %s",strerror(errno) );
508  return -1;
509  }
510 #endif
511  return 0 ;
512 }
513 
514 //####################################################################
515 //
516 //####################################################################
517 void gl3Conductor::setBField ( float bField ){
518  for ( int i = 0 ; i < maxEvents ; i++ ) {
519  event[i].setBField ( bField ) ;
520  }
521 }
522 //####################################################################
523 //
524 //####################################################################
525 void gl3Conductor::setHitProcessing ( int hitPro ){
526  hitProcessing = hitPro ;
527  for ( int i = 0 ; i < maxEvents ; i++ ) {
528  event[i].setHitProcessing ( hitPro ) ;
529  }
530 }
531 //####################################################################
532 //
533 //####################################################################
534 void gl3Conductor::setMaxSectorNForTrackMerging ( int _maxSectorNForTrackMerging ){
535  maxSectorNForTrackMerging = _maxSectorNForTrackMerging ;
536  for ( int i = 0 ; i < maxEvents ; i++ ) {
537  event[i].setMaxSectorNForTrackMerging ( _maxSectorNForTrackMerging ) ;
538  }
539 }
540 //####################################################################
541 //
542 //####################################################################
543 int gl3Conductor::setup ( St_l3_Coordinate_Transformer* _trans,
544  int maxEventsIn, int maxAlgorithmsIn ) {
545  //
546  communicationsFlag = 1 ;
547  event = 0 ;
548  algorithm = 0 ;
549  runNumber = 0 ;
550  maxTokens = 4096 ;
551  tokenIndex = new int[maxTokens+1];
552 
553 
554  maxEvents = maxEventsIn ;
555  maxAlgorithms = maxAlgorithmsIn ;
556 
557  event = new gl3Event[maxEvents] ;
558  summary = new L3_summary[maxEvents];
559 
560  summaryData = (L3_SUMD*) malloc( maxEvents * (sizeof(L3_SUMD) +
561  (maxAlgorithms-1)*sizeof(algorithm_data)));
562 
563  algorithm = new pGl3Algorithm[maxAlgorithms] ;
564  for (int i=0; i<maxAlgorithms;i++) algorithm[i]=NULL;
565 
566  nEvents = 0 ;
567  nAlgorithms = 0 ;
568  //
569  for ( int i = 0 ; i < maxTokens ; i++ ) tokenIndex[i] = 0 ;
570 
571  //
572  // Setup communications
573  //
574 #ifdef GL3ONLINE
575  if ( communicationsFlag ){
576  if(setCommunications() )
577  return -1;
578  }
579 #endif
580 
581  hitProcessing = 0 ;
582  for ( int i = 0 ; i < maxEvents ; i++ ) {
583  event[i].setHitProcessing ( hitProcessing ) ;
584  event[i].setCoordinateTransformer ( _trans ) ;
585  }
586 
587  ftfLog("analysis framework set up\n");
588 
589  return 0 ;
590 }
591 //####################################################################
592 //
593 //####################################################################
594 int gl3Conductor::writeHistos ( int maxBytes, char *buffer )
595 {
596 
597  gl3HistoContainer* container = (gl3HistoContainer *)buffer ;
598 
599  ftfLog ( "nHistos %d \n", histoList.size() ) ;
600  container->runNumber = runNumber ;
601  container->nHistos = histoList.size();
602 
603  char* pointer = (char *)&(container->buffer) ;
604  char* endBuffer = buffer + maxBytes ;
605  int nBytes ;
606  int nTotalBytes = 6; // offset coming from gl3HistoContainer
607  //gl3Histo hTest ;
608 
609  list<gl3Histo*>::iterator histo;
610  for(histo=histoList.begin(); histo!=histoList.end(); histo++) {
611 
612  nBytes = (*histo)->Write ( endBuffer-pointer, pointer ) ;
613  if ( nBytes <= 0 ) {
614  ftfLog ( "gl3Container::writeHistos %d byte long buffer is too short \n", maxBytes ) ;
615  return 0 ;
616  }
617  // ftfLog ( "nBytes written %d pointer %x \n", nBytes, pointer ) ;
618  nTotalBytes += nBytes ;
619  if ( nTotalBytes > maxBytes ) {
620  ftfLog ( "gl3Conductor::writeHistos: nTotalBytes %d max %d\n", nTotalBytes, maxBytes ) ;
621  return -1 ;
622  }
623  pointer += nBytes * sizeof(char) ;
624  }
625  container->nBytes = nTotalBytes ;
626  ftfLog ( "gl3Conductor::writeHistos: histos %d Bytes %d \n",
627  histoList.size(), nTotalBytes ) ;
628 
629  return nTotalBytes ;
630 }
631 
632 
633 
634 //####################################################################
635 //
636 //####################################################################
637 int gl3Conductor::getFreeEventIndex()
638 {
639  int freeEventIndex = -1 ;
640  for ( int i = 0 ; i < maxEvents ; i++ ) {
641  if ( !(event[i].getBusy() ) ) {
642  freeEventIndex = i ;
643  nEvents++ ;
644  break ;
645  }
646  }
647 
648  return freeEventIndex;
649 }
650 
651 //####################################################################
652 //
653 //####################################################################
654 int gl3Conductor::getTokenIndex(int token)
655 {
656  if (token < 0 || token > 4096) {
657  ftfLog("gl3Conductor: token [%d] out of bounds \n", token );
658  return -1;
659  }
660 
661  int index = tokenIndex[token];
662 
663  if (index < 0 || index >= maxTokens) {
664  ftfLog("gl3Conductor: event index %d out of bounds \n", token );
665  return -2;
666  }
667 
668  return index;
669 };
670 
671 
672 
673 //####################################################################
674 //
675 //####################################################################
676 void gl3Conductor::resetTimer()
677 {
678  lastTimeEntry=0;
679  cpuTimes.clear();
680  realTimes.clear();
681 
682  cpuTimes.reserve(5+nAlgorithms);
683  realTimes.reserve(5+nAlgorithms);
684 
685  timingMark();
686 }
687 
688 void gl3Conductor::timingMark()
689 {
690  cpuTimes[lastTimeEntry] = clock();
691  realTimes[lastTimeEntry] = realcc();
692 
693  lastTimeEntry++;
694 }
695 
696 void gl3Conductor::allocateTimingHistos()
697 {
698 #ifdef GL3ONLINE
699  timingHistos.resize(3+nAlgorithms);
700 
701  timingHistos[0] = new gl3Histo("time_read_l3",
702  "Timing: read L3 data",
703  50,0,300);
704 
705  timingHistos[1] = new gl3Histo("time_read_trg",
706  "Timing: read TRG data",
707  50,0,100);
708 
709  char hid[30], htitle[100];
710  for(int i=0; i<nAlgorithms;i++) {
711 
712  sprintf(hid, "time_alg_%d", i);
713  sprintf(htitle, "Timing: algorithms %d", i);
714  timingHistos[2+i] = new gl3Histo(hid, htitle,
715  60,0,30);
716  }
717 
718  timingHistos[2+nAlgorithms] = new gl3Histo("time_total",
719  "Timing: total",
720  50,0,300);
721 
722 
723 
724  for(int i=0;i<timingHistos.size();i++) {
725  histoList.push_back(timingHistos[i]);
726  }
727 #endif
728 }
729 
730 void gl3Conductor::fillTimingHistos()
731 {
732 #ifdef GL3ONLINE
733  timingHistos[0]->Fill(double(realTimes[1] - realTimes[0])/ccPerMs);
734  timingHistos[1]->Fill(double(realTimes[2] - realTimes[1])/ccPerMs);
735 
736  for(int i=0; i<nAlgorithms;i++) {
737  timingHistos[2+i]->Fill(double(realTimes[3+i] - realTimes[2+i])/ccPerMs);
738  }
739 
740  timingHistos[2+nAlgorithms]->
741  Fill(double(realTimes[lastTimeEntry-1] - realTimes[0])/ccPerMs);
742 
743  ftfLog("total time: %f\n",
744  double(realTimes[lastTimeEntry-1] - realTimes[0])/ccPerMs);
745 #endif
746 }
747 
748 void gl3Conductor::printTiming()
749 {
750  for (int i=1; i<lastTimeEntry;i++) {
751  ftfLog("gl3Conductor: timing step %2d: CPU: %8f real: %8f\n",
752  i, (double)cpuTimes[i]-cpuTimes[i-1]/CLOCKS_PER_SEC,
753  (double)(realTimes[i]-realTimes[i-1])/ccPerMs);
754  }
755 }
756 
757 
758 
759 
760 //####################################################################
761 //
762 //####################################################################
763 // void gl3Conductor::printTiming ( ){
764 // ftfLog ( "********************************\n" ) ;
765 // ftfLog ( "* gl3 timing *\n" ) ;
766 // ftfLog ( "* Total: Real %5.0f (ms) \n", 1000.*totalRealTime ) ;
767 // ftfLog ( "* CPu %5.0f (ms) \n", 1000.*totalCpuTime ) ;
768 // ftfLog ( "* Algorithm Real Cpu *\n" ) ;
769 // ftfLog ( "* ( ) ( ) *\n" ) ;
770 // for ( int i = 0 ; i < nAlgorithms ; i++ ) {
771 // ftfLog ( "* %d %7.1f %7.1f *\n",
772 // i, 100.*algorithmRealTime[i]/totalRealTime,
773 // 100.*algorithmCpuTime[i]/totalCpuTime ) ;
774 // }
775 // ftfLog ( "********************************\n" ) ;
776 // }
int Fill(double x, double weight=1)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ...
Definition: gl3Histo.cxx:53