MIDAS
Loading...
Searching...
No Matches
HandleSIS.cxx
Go to the documentation of this file.
1//
2// SIS event handling routines for ALPHA ROOT analyzer
3//
4// Name: HandleSIS.cxx
5// Author: R.Hydomako
6//
7// $Id$
8//
9// $Log: HandleSIS.cxx,v $
10// Revision 1.42 2006/09/13 12:07:24 alpha
11// RAH - Added the integratio to the fine details display
12//
13// Revision 1.41 2006/09/11 13:38:24 alpha
14// RAH - Scrolling now properly works in reversed direction
15//
16// Revision 1.40 2006/09/09 21:57:49 alpha
17// RAH - Added fine SIS display
18//
19// Revision 1.39 2006/09/07 05:47:24 alpha
20// RAH - Changed the filename written to the root file to include spill number
21//
22// Revision 1.38 2006/08/24 11:47:48 alpha
23// RAH - Cleaned up some of the code, tried to made it more transparent
24//
25// Revision 1.37 2006/08/07 09:27:08 alpha
26// RAH - got rid of all the SISFrame stuff
27//
28// Revision 1.36 2006/07/28 19:33:53 alpha
29// RAH - Moved all the processing into the GUI classes. Very slow, will have to rearrange processes
30//
31// Revision 1.35 2006/07/28 13:10:31 alpha
32// RAH - All the base code added for a global SIS GUI frame
33//
34// Revision 1.34 2006/07/22 13:35:45 alpha
35// RAH- beamSpill and PbarsInAd into gbeamSpill and gPbarsInAd
36//
37// Revision 1.33 2006/07/21 13:59:12 alpha
38// RAH - Switches histograms are only filled when not zero
39//
40// Revision 1.32 2006/07/20 14:45:26 alpha
41// RAH - Removed some unnesessary gOutputFile->cd()s
42//
43// Revision 1.31 2006/07/19 11:06:35 alpha
44// RAH - Histograms now placed in the rihg directories
45//
46// Revision 1.30 2006/07/17 14:41:29 alpha
47// RAH- Now, hopefully, the per second works
48//
49// Revision 1.29 2006/07/17 13:44:14 alpha
50// RAH- Hopefully fixed the per second plotting for the online monitor
51//
52// Revision 1.28 2006/07/16 17:27:18 alpha
53// RAH- Changed how the Online Monitor per second ploting is done
54//
55// Revision 1.27 2006/07/16 13:53:17 alpha
56// RAH- Fixed up the scrolling to work with when running offline
57//
58// Revision 1.26 2006/07/14 12:41:03 alpha
59// RAH- Changed how the online monitor steps through the data
60//
61// Revision 1.25 2006/07/13 14:15:21 alpha
62// RAH- Added offline handling (changed how the routines handle the current time)
63//
64// Revision 1.24 2006/07/11 19:45:28 alpha
65// RAH- Changed how the online monitor fill the histograms
66//
67// Revision 1.23 2006/07/10 16:27:39 alpha
68// RAH- Time between pulses histogram now saved at the end of run
69//
70// Revision 1.22 2006/07/09 12:50:54 alpha
71// RAH- Added code to histogram the time between pulses on a single SIS channel
72//
73// Revision 1.21 2006/07/07 16:40:43 alpha
74// RAH- Stopped the online monitor from starting up on pedestal runs
75//
76// Revision 1.20 2006/07/03 12:43:03 alpha
77// RAH- Made the SIS online monitor apart of alpharoot.ini
78//
79// Revision 1.19 2006/06/29 11:34:46 alpha
80// RAH- Made it so that the file paths are read from alpharoot.ini
81//
82// Revision 1.18 2006/06/27 12:19:25 alpha
83// RAH- Fixed the online histograms so that you can see everything if there is more than one per panel
84//
85// Revision 1.17 2006/06/26 14:36:59 alpha
86// RAH- Got rid of all the list and ADC stuff
87//
88// Revision 1.16 2006/06/26 12:36:42 alpha
89// RAH- Added a more sophisticated online monitor, which initializes from onlinemonitor.txt
90//
91// Revision 1.15 2006/06/23 08:47:23 alpha
92// RAH- Fixed the parsing of the histogram titles
93//
94// Revision 1.14 2006/06/22 16:14:06 alpha
95// RAH- Added startevents to the switching routine, changed the parsing of the switches reading
96//
97// Revision 1.13 2006/06/22 13:16:16 alpha
98// RAH- Added a per bin histogram display type
99//
100// Revision 1.12 2006/06/21 13:37:17 alpha
101// RAH- Added a list structure and redid the switches routine
102//
103// Revision 1.11 2006/06/18 08:28:26 alpha
104// RAH- Put all the switches stuff into structs
105//
106// Revision 1.10 2006/06/15 19:27:18 alpha
107// RAH- Changing the parsing of switches.txt (still working on it)
108//
109// Revision 1.9 2006/06/15 18:11:11 alpha
110// RAH- Changed some formatting, removed some swithces code
111//
112
113// Libraries
114#include <TSystem.h>
115#include <TApplication.h>
116#include <TTimer.h>
117#include <TCanvas.h>
118#include <TH1.h>
119#include <TStyle.h>
120#include <TFile.h>
121#include <TRootEmbeddedCanvas.h>
122
123#include "Globals.h"
124
125// Switches variables
126
127const int kMaxSwitches = 20;
129
130int tptr = 0;
131bool tinit = false;
132
133
134struct SWITCH {
135 int switchtype; // the type of switch: 0-repeat, 1-one time only 2-reset
136 int startchannel; // the channel that the start signal comes in from
137 int stopchannel; // the channel where the stop signal comes in from
138 int numstartevents; // number of start events before turning on the switch
139 int numstopevents; // number of stop events before turning off the switch
140 int startthr; // the number of counts in the start channel to turn on the switch
141 int stopthr; // the number of counts in the stop channel to turn off the switch
142 int numbins; // number of bins in the histogram
143 double xmin; // minimum histogram bin
144 double xmax; // maximum histogram bin
145 int channeltoread; // channel to histogram
146 int displaytype; // type of histogram to display 0-per bin 1-per second
147 char title[80]; // title of the histogram
148
149 bool switchon; // switch on or off
150 bool keepgoing; // whether to keepgoing (used for type 1)
151
152 int startcounts; // the number of events from the start channel
153 int stopcounts; // the number of events from the stop channel
154 int eventcounts; // the number of events inputed from the channel being read
155 int timescalled; // the number of times the switch is flipped
156
157 double start; // time the switch was turned on
158 TH1D *histo; // the histogram
159};
160
161SWITCH switches[kMaxSwitches]; // the array of switches
162
163
164// Online Monitor Variables
165
166const int kNumPanels = 64;
167const int kNumOnlineHistos = 5;
168
181
184
185int numpanels = 0;
186int xpanels = 2;
187int ypanels = 8;
188double textsize = 0.1;
189double xlabelsize = .1;
190double ylabelsize = .1;
191double ylabeloffset = .01;
193int xcanvas = 1200;
194int ycanvas = 800;
195
199double dSIStextsize = 0.1;
200double dSISxlabelsize = .1;
201double dSISylabelsize = .1;
202double dSISylabeloffset = .01;
204int dSISxcanvas = 1200;
205int dSISycanvas = 800;
206
209double gtfs = 0.;
210
211// Routine to convert the Clock value into a Time (in seconds)
212
214{
215 const double freq = 10000000.0;
216
217 if (gSaveTime == 0)
218 {
220 gSaveTime = time(NULL);
221 }
222
223 return gSaveTime + (clock - gSaveClock)/freq;
224}
225
226// Routine to reset the global clock and time values
227
229{
230 gSaveClock = 0;
231 gSaveTime = 0;
232}
233
234// Routine to read all the switches from switches.txt
235
237{
239 fswitches = fopen(gSwitchesPath,"r"); // open the switches file
240
241 char inputstring[200]; // buffer for the input data
242
243 if(fswitches != NULL) // try to open the file
244 {
245 printf("Switches being read from the file: %s\n",gSwitchesPath);
246 while(!feof(fswitches)) //loop over all lines in the file
247 {
248 char dummychar[5];
249 if(fgets(dummychar,2,fswitches) == NULL) break; // safety check for end of file
250 else fseek(fswitches,-1,SEEK_CUR); // rewind if not end of file
251
252 //Parse switches.txt line by line
253
254 fgets(inputstring,199,fswitches); // put the line into a buffer string
255 if(strchr(inputstring,'#')==NULL) // if there is a #, then it is a comment
256 {
257 //printf("string: %s\n",inputstring);
258
259 char *parsestring;
260 parsestring = strtok(inputstring, " "); // Parse the type of switch
262
263 parsestring = strtok(NULL, " "); // Parse the channel to switch on
265
266 parsestring = strtok(NULL, " "); // Parse the channel to switch off
268
269 parsestring = strtok(NULL, " "); // Parse the number of stop channel events before
271
272 parsestring = strtok(NULL, " "); // Parse the number of stop channel events before
274
275 parsestring = strtok(NULL, " "); // Parse the number of stop channel events in the channel
276 switches[numswitches].startthr= atoi(parsestring);// before switching on
277
278 parsestring = strtok(NULL, " "); // Parse the number of stop channel events in the channel
279 switches[numswitches].stopthr= atoi(parsestring);// before switching off
280
281 parsestring = strtok(NULL, " "); // Parse the number of histogram bins
283
284 parsestring = strtok(NULL, " "); // Parse the minimum histogram bin
286
287 parsestring = strtok(NULL, " "); // Parse the max histogram bin
289
290 parsestring = strtok(NULL, " "); // Parse the channel to histogram
292
293 parsestring = strtok(NULL, " "); // Parse the displaytype
295
296 parsestring++;
297
298 // then to parse the title
299 int i = 0;
300 char title=false;
301 while(i<100) // safety check
302 {
303 parsestring++;
304 if((!isspace(*parsestring))||(title==true))
305 {
306 title=true;
307 if (*parsestring == 10 || *parsestring == 13 || *parsestring == 0)
308 break;
310 }
311 }
312 //printf("%s\n",switches[numswitches].title);
313 numswitches++;
314 }
315 }
316 //printf("Number of switches: %d\n",numswitches);
318 }
319 else
320 printf("Cannot open %s!\n",gSwitchesPath);
321
323 printf("Exceeded maximum number of switches!\n");
324}
325
327
328bool DetailsRecord[kNumberofDetailChannels] = {false,false,false,false,false};
330char* DetailsTitles[kNumberofDetailChannels] = {"PMT OR","Pbar TimeStamps","Mixing TimeStamps","Pbar Sequence Start","Mixing Sequence Start"};
332
333const double DetailsLength = 3.0; // JWS CHANGED!!!! from 10.0
334
335const int ADchannel = 1;
336double detailsStartTime = 0.0;
337
338double detailsmin = 0.2;
339double detailsmax = 0.4;
340
341int Integral = 0;
342
343void CheckDetails(int Channel, double counts, uint64_t clock)
344{
345 if(counts!=0) {
346 if(Channel == ADchannel) {
347 if(DetailsRecord[0] == false) {
349
350 char title[80];
351
352 for(int i = 0;i<kNumberofDetailChannels;i++) {
353 sprintf(title,"%s, Run %d, Spill %d",DetailsTitles[i],gRunNumber,gbeamSpill);
354 DetailsHisto[i] = new TH1D(title,title,200,0,DetailsLength);
355 gStyle->SetOptStat(kTRUE);
356 //DetailsHisto[i] = new TH1D(title,title,20,detailsmin,detailsmax);
357
358 DetailsRecord[i] = true;
359 }
360 Integral = 0;
361 }
362 else {
363// printf("AD trigger while details still recording\n");
364 }
365 }
366 for(int i = 0;i < kNumberofDetailChannels;i++) {
367 if (Channel == DetailsChannels[i])
368 {
369 if(DetailsRecord[i] == true){
371 for(int j=0;j<kNumberofDetailChannels;j++) {
372 DetailsHisto[j]->Write();
373 if(j==0)
374 printf("Spill: %d, Integral: %d\n",gbeamSpill,Integral);
375
376 DetailsRecord[j]=false;
377
378 if(!gSISDetails) {
379 gSISDetails = new TCanvas("SIS Fine Details","SIS Fine Details",600,900);
380 gSISDetails->Divide(1,kNumberofDetailChannels,0.001,0.001);
381
382 //gStyle->SetOptStat(kFALSE); // Turn off the statistics for the online histograms
383 gStyle->SetTitleFontSize(0.09);
384 }
385
386 gSISDetails->cd(j+1);
387
388 if(j==0)
389 {
390 char text[80];
391 sprintf(text,"Integral (%lf-%lf): %d",detailsmin,detailsmax,Integral);
392 TText *txt = new TText(.2,2,text);
393 txt->SetTextSize(0.1);txt->SetTextColor(1);
394 DetailsHisto[j]->GetListOfFunctions()->Add(txt);
395 }
396 DetailsHisto[j]->Draw();
397 }
398 gSISDetails->Modified();
399 gSISDetails->Update();
400 }
401 else {
404 Integral++;
405 }
406 }
407 else{
408 // Don't record
409 }
410 }
411 }
412 }
413}
414
415
416
417// Check the inputted value against the defined switches
418
419void CheckTriggers(int Channel, double counts, uint64_t clock)
420{
421 for(int i=0;i<numswitches;i++) //loop over all switches
422 {
423 if(switches[i].keepgoing==true) // used for switch type 1 (when turned off, stays off)
424 {
425 if((switches[i].startchannel==Channel)&&(switches[i].switchon==false)&&(counts==switches[i].startthr)) // turn on the switch
426 {
427 if(switches[i].startcounts==switches[i].numstartevents)
428 {
429 switches[i].switchon=true;
431// printf("Switch %d - On!\n",i);
432
433 char title[80];
434 sprintf(title,"%s, Run %d, Spill Number %d",switches[i].title,gRunNumber,gbeamSpill);
435
436 switches[i].histo = new TH1D(title,switches[i].title,switches[i].numbins,switches[i].xmin,switches[i].xmax);
438
439 //printf("i: %d, clock: %ld, start: %lf, gSaveClock: %d, gSaveTime: %d\n", i,(long int)clock,switches[i].start,(int)gSaveClock,(int)gSaveTime);
440
441 switches[i].stopcounts = 0;
443 }
444 else switches[i].startcounts++;
445 }
446 else if ((switches[i].stopchannel==Channel)&&(switches[i].switchon==true)&&(counts==switches[i].stopthr)) // a event in stop channel
447 {
448 if(switches[i].stopcounts==switches[i].numstopevents) // and if there have been enough endsignals
449 {
450// printf("Switch %d - Off!\n", i);
451 switches[i].switchon= false;
452
453 switches[i].histo->Write();
454
458 if(switches[i].switchtype==1) // no repeating
459 switches[i].keepgoing = false;
460 else if (switches[i].switchtype==2) // reseting
461 {
462 switches[i].switchon=true;
464// printf("Resetting switch %d!\n",i);
465
466 delete switches[i].histo;
468
469 char title[80];
470 sprintf(title,"%s, Run %d, Spill Number %d",switches[i].title,gRunNumber,gbeamSpill);
471
472 switches[i].histo = new TH1D(title,switches[i].title,switches[i].numbins,switches[i].xmin,switches[i].xmax);
474 }
475 }
476 else switches[i].stopcounts++;
477 }
478 if((switches[i].switchon == true)&&(switches[i].stopcounts<=switches[i].numstopevents))
479 {
480 if(switches[i].displaytype==0) // display the results per bin
481 {
482 if(Channel==switches[i].channeltoread) {
483 switches[i].histo->Fill(switches[i].eventcounts,counts);
485 }
486 }
487 else if(Channel==switches[i].channeltoread)
488 {
489 if(counts!=0) {
491 switches[i].histo->Fill(plottime,counts);
492 }
493 }
494 }
495 }
496 }
497}
498
499bool mixingsequence = false;
500bool pbarsequence = false;
501
502bool mixingrecording = false;
503bool pbarrecord = false;
504
507
509int pbarindex = 0;
510
512
514
515void CheckMixingTriggers(int Channel, double counts, uint64_t clock)
516{
517 int sequencestartchannel = 7;
519 int recordingchannel = 2;
520
521 if(counts!=0){
522
524
525 if(mixingsequence == false) { // Startup
526 printf("Starting of mixingsequence\n");
527
528 mixingsequence = true;
529 mixingindex = 0;
530 }
531 else if (mixingsequence == true) { // Reset
532
533 printf("Mixing dump start signal called when already in a sequence!\n");
534
535 }
536 }
537 else if(Channel == mixingtimestampchannel) { // Mixing timestamp to check
538 if(mixingsequence == true) {
539
540 // printf("mtimestamp!\n");
541
542 mixingindex++;
543
544 if((mixingrecording==false)&&(gmdump.singledump[dumpnumber].steps[mixingindex]==1)){
545 mixingrecording = true;
546
547 printf("1! Step: %d\n",mixingindex);
548 //start histogram here
549 dumpnumber++;
550
551 char title[80];
552 sprintf(title,"Dump (mixing) number %d, spill %d, run%d",dumpnumber,gbeamSpill,gRunNumber);
553
554 if(mixinghisto){
555 mixinghisto->Write();
556 delete mixinghisto;
558 }
559 mixinghisto = new TH1D(title,title,15000,0,15000);
560
562 }
563 else if ((mixingrecording==true)&&(gmdump.singledump[dumpnumber].steps[mixingindex]==0)){ // Dump finished, write histogram
564 mixingrecording = false;
565
566 //int mixingintegral = mixinghisto->Integral();
567 mixinghisto->Write();
568 }
569 }
570 else {
571 // printf("Mixing timestamp when no mixing sequence!\n");
572 }
573
574 if(mixingindex == gmdump.singledump[dumpnumber].totalsteps){
575 // printf("Max size (%d)!\n",gmdump.singledump[dumpnumber].totalsteps);
576 mixingrecording = false;
577 mixingsequence = false;
578 }
579
580 }
581 else if ((Channel == recordingchannel)&&(mixingrecording)) {
582 printf("Record!\n");
583 if(mixinghisto){
585 }
586 else
587 printf("No histogram to record to!\n");
588 }
589
590 }
591}
592
593void CheckPbarTriggers(int Channel, double counts, uint64_t clock)
594{
595// int sequencestartchannel = 6;
596// int pbartimestampchannel = 4;
597
598}
599
600
601// Moves through the SIS data, sends the next event to be check against the switches
602// (Called once a second)
603
605{
606 if(gIsRunning==true) // proceed only when running
607 {
608 gOutputFile->cd("SIS");
609 if((gSisData->cptr<gSisData->wptr)&&(gSisData->cptr<gSisData->wmax)) // when the read pointer is behind both the write pointer and max
610 {
611 while(gSisData->cptr<gSisData->wptr) // send all the unchecked events to check against the switches
612 {
613 for(int i = 0;i<kMaxSisChannels;i++)
614 {
615 int channel = i;
616 double counts = gSisData->sisChannels[i].sisData[gSisData->cptr];
617 uint64_t clock = gSisData->sisClock[gSisData->cptr];
618
621
623
625 CheckDetails(channel,counts,clock);
626 }
627 gSisData->cptr++;
628 }
629 }
630 else if ((gSisData->cptr>gSisData->wptr)&&(gSisData->cptr<gSisData->wmax)) // when the write pointer has gone back to zero, but the read pointer hasn't yet
631 {
632 while(gSisData->cptr<gSisData->wmax)
633 {
634 for(int i = 0;i<kMaxSisChannels;i++)
635 {
636 int channel = i;
637 double counts = gSisData->sisChannels[i].sisData[gSisData->cptr];
638 uint64_t clock = gSisData->sisClock[gSisData->cptr];
639
642
644
646 CheckDetails(channel,counts,clock);
647 }
648 gSisData->cptr++;
649 }
650 }
651 else if((gSisData->cptr>gSisData->wptr)&&(gSisData->cptr==gSisData->wmax)) // if the read pointer has readed the maximum (go back to zero)
652 gSisData->cptr = 0;
653
654 //printf("cptr: %d, wptr: %d, wmax: %d\n",gSisData->cptr,gSisData->wptr, gSisData->wmax);
655 gOutputFile->cd("../");
656 }
657}
658
659
660// Routine to handle the incoming SIS data -- write the data into an ordered buffer
661
662void HandleSIS(int numChan,int size,const void*ptr)
663{
664 const uint32_t *sis = (uint32_t*)ptr;
665// printf("SIS data size %d, ",size);
666
667 assert(gSisData);
668
669 int i;
670 for (i=0; i<size; i+=numChan, sis+=numChan)
671 {
672 //printf("bucket %d, data: %d %d %d %d\n",i,sis[16],sis[17],sis[18],sis[19]);
673 uint64_t clock = sis[0];
674
675 for (int j=0; j<numChan; j++)
676 {
677 gSisData->sisChannels[j].sisData[gSisData->wptr] = sis[j];
678 }
679
680 gSisData->clock += clock;
681 gSisData->sisClock[gSisData->wptr] = gSisData->clock;
682
683 gSisData->wptr++;
684 if (gSisData->wptr >= kMaxSisBufferSize)
685 gSisData->wptr = 0;
686
687 if (gSisData->wptr > gSisData->wmax)
688 gSisData->wmax = gSisData->wptr;
689 }
690 assert(i==size);
691
692 //printf("wptr: %d\n",gSisData->wptr);
693
694 time_t now = time(NULL);
695
696 static time_t gNow = 0;
697 if (now > gNow + 10)
698 {
699 gNow = now;
700 double sistime = clock2time(gSisData->clock);
701 printf("time drift: %d %f %f\n",(int)now,sistime,sistime-now);
702 }
703}
704
705
706
708{
709 FILE *fmonitor = NULL;
710 fmonitor = fopen(gOLMPath,"r"); // open the switches file
711
712 char inputstring[120]; // buffer for the input data
713 bool divideinit = false;
714
715 if(fmonitor != NULL) // try to open the file
716 {
717 printf("Online Monitor values being read from file: %s\n",gOLMPath);
718 while(!feof(fmonitor)) //loop over all lines in the file
719 {
720 char dummychar[5];
721 if(fgets(dummychar,2,fmonitor) == NULL) break; // safety check for end of file
722 else fseek(fmonitor,-1,SEEK_CUR); // rewind if not end of file
723
724 //Parse onlinemonitor.txt line by line
725
726 fgets(inputstring,119,fmonitor); // put the line into a buffer string
727 if(strchr(inputstring,'#')==NULL) // if there is a #, then it is a comment
728 {
729 //printf("string: %s\n",inputstring);
730 char *parsestring; // buffer to parse
731
732 if(divideinit==false) // grab the first line (window options)
733 {
734 parsestring = strtok(inputstring, " "); // Parse the number of columns
736
737 parsestring = strtok(NULL, " "); // Parse the number of rows
739
740 parsestring = strtok(NULL, " "); // Parse the size of the text
742
743 parsestring = strtok(NULL, " "); // Parse the size of the x labels
745
746 parsestring = strtok(NULL, " "); // Parse the size of the y labels
748
749 parsestring = strtok(NULL, " "); // Parse the size of the y label offset
751
752 parsestring = strtok(NULL, " "); // Parse if to show exponents on the y axis
754
755 parsestring = strtok(NULL, " "); // Parse if to show exponents on the y axis
757
758 parsestring = strtok(NULL, " "); // Parse if to show exponents on the y axis
760
761 divideinit=true;
762 }
763 else // then grab the rest of the file
764 {
765 parsestring = strtok(inputstring, " "); // Parse the panel number
767
768 parsestring = strtok(NULL, " "); // Parse the number of histograms in the panel
770
772 {
773 printf("Too many histograms in panel %d!\n",numpanels);
774 break;
775 }
776 parsestring++;
777
778 // then to parse the title
779 int i = 0;
780 char title=false;
781 while(i<100) // safety check
782 {
783 parsestring++;
784 if((!isspace(*parsestring))||(title==true))
785 {
786 title=true;
787 if (*parsestring == 10 || *parsestring == 13 || *parsestring == 0)
788 break;
790 }
791 }
792
793 //printf("Number of histograms: %d, title: %s\n",onlinemonitor[numpanels].nhistos,onlinemonitor[numpanels].title);
794 for(int i=0;i<onlinemonitor[numpanels].nhistos;i++)
795 {
797 if(strchr(inputstring,'#')==NULL) // if there is a #, then it is a comment
798 {
799 parsestring = strtok(inputstring, " "); // Parse the channel to read
801 parsestring = strtok(NULL, " "); // Parse the number of bins
803 parsestring = strtok(NULL, " "); // Parse the minimum bin
805 parsestring = strtok(NULL, " "); // Parse the max bin
807 parsestring = strtok(NULL, " "); // Parse the colour
809 parsestring = strtok(NULL, " "); // Parse the display type
811 }
812 }
813 numpanels++;
815 {
816 printf("Exceeded maximum number of panels!\n");
817 break;
818 }
819 }
820 }
821 }
823 }
824 else
825 {
826 printf("Cannot open %s!\n",gOLMPath);
827 }
828
829 if(gMainWindow==NULL)
830 {
831 gMainWindow = new TCanvas("SIS Display","SIS Display",xcanvas,ycanvas);
832 gMainWindow->Divide(xpanels,ypanels,0.001,0.001);
833 }
834
835 gStyle->SetOptStat(kFALSE); // Turn off the statistics for the online histograms
836 gStyle->SetTitleFontSize(textsize);
837
838 if(onlinemonitor[0].onlinehisto[0]!=NULL)
839 {
840 for(int i=0;i<numpanels;i++)
841 {
842 for(int j=0;j<onlinemonitor[i].nhistos;j++)
843 {
844 delete onlinemonitor[i].onlinehisto[j];
845 }
846 }
847 }
848
849 gROOT->cd(); // Move outside gOutputFile so that these histograms
850 char title[80]; // aren't affected between runs
851 for(int i=0;i<numpanels;i++)
852 {
853 gMainWindow->cd(onlinemonitor[i].panelnumber);
854 for(int j=0;j<onlinemonitor[i].nhistos;j++)
855 {
856 if(j==(onlinemonitor[i].nhistos-1))
857 {
859 }
860 else
861 {
862 char dummytitle[80];
863 sprintf(dummytitle,"%s, Channel %d",onlinemonitor[i].title,onlinemonitor[i].histochannel[j]);
865 }
866 switch(onlinemonitor[i].colour[j])
867 {
868 case 0:
869 onlinemonitor[i].onlinehisto[j]->SetLineColor(kBlack);
870 break;
871 case 1:
872 onlinemonitor[i].onlinehisto[j]->SetLineColor(kRed);
873 break;
874 case 2:
875 onlinemonitor[i].onlinehisto[j]->SetLineColor(kBlue);
876 break;
877 default:
878 onlinemonitor[i].onlinehisto[j]->SetLineColor(kBlack);
879 }
880 onlinemonitor[i].onlinehisto[j]->GetYaxis()->SetNoExponent(ynoexponent);
881 onlinemonitor[i].onlinehisto[j]->SetLabelSize(xlabelsize,"X");
882 onlinemonitor[i].onlinehisto[j]->SetLabelSize(ylabelsize,"Y");
883 onlinemonitor[i].onlinehisto[j]->SetLabelOffset(ylabeloffset,"Y");
884 }
885 }
886 if(gOutputFile!=NULL)
887 {
888 sprintf(title,"data/run%d.root:/",gRunNumber);
889 gROOT->Cd(title); // Move back into gOutputFile
890 }
891 else
892 {
893 printf("Data file improperly initialized\n");
894 return;
895 }
896 gStyle->SetOptStat(kTRUE); // Turn the statistics back on for the other histograms
897 //gStyle->SetTitleFontSize();
898}
899
900
901// Routine to update the online histograms (called once a second)
902
904{
905 double now = 0;
906 double datatime = 0;
907 double diff = 0;
908 uint32_t data = 0;
909
910
911 if(gMainWindow!=NULL)
912 {
913 // Reset and fill all the online histograms
914 for(int i=0;i<numpanels;i++)
915 {
916 gMainWindow->cd(onlinemonitor[i].panelnumber);
917 for(int j=0;j<onlinemonitor[i].nhistos;j++)
918 {
919 onlinemonitor[i].onlinehisto[j]->Reset();
920
921 // Display the data per bin
922
923 if(onlinemonitor[i].displaytype[j]==0)
924 {
925 if(gSisData->wptr==gSisData->wmax) // for the first loop through the buffer
926 {
927 if((gSisData->wptr-(int)onlinemonitor[i].xmax[j])<=0) // when the data doesn't fill the whole histogram
928 {
929 for(int k = 0;k<gSisData->wptr;k++)
930 onlinemonitor[i].onlinehisto[j]->Fill(gSisData->wptr-k,gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k]);
931 }
932 else // fill the whole histogram
933 {
934 for(int k = (gSisData->wptr-(int)onlinemonitor[i].xmax[j]);k<gSisData->wptr;k++)
935 onlinemonitor[i].onlinehisto[j]->Fill(gSisData->wptr-k,gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k]);
936 }
937 }
938 else // after the buffer has been looped through
939 {
940 if((gSisData->wptr-(int)onlinemonitor[i].xmax[j])<=0)
941 {
942 for(int k = 0;k<gSisData->wptr;k++) // the data from the front of the buffer
943 onlinemonitor[i].onlinehisto[j]->Fill(gSisData->wptr-k,gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k]);
944 // the data from the end of the buffer
945 for(int k = (gSisData->wmax-(int)onlinemonitor[i].xmax[j]+gSisData->wptr);k<gSisData->wmax;k++)
946 onlinemonitor[i].onlinehisto[j]->Fill(gSisData->wmax+gSisData->wptr-k,gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k]);
947 }
948 else // data fills the whole histogram
949 {
950 for(int k = (gSisData->wptr-(int)onlinemonitor[i].xmax[j]);k<gSisData->wptr;k++)
951 onlinemonitor[i].onlinehisto[j]->Fill(gSisData->wptr-k,gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k]);
952 }
953 }
954 }
955
956 // Display per second
957
958 else if(onlinemonitor[i].displaytype[j]==1) {
959
960 // If the data buffer hasn't looped and gone back the the beginning
961
962 if(gSisData->wptr==gSisData->wmax)
963 {
964 // While all the data can be fitted onto one histogram
965
966 if((clock2time(gSisData->sisClock[gSisData->wptr-1])-clock2time(gSisData->sisClock[0])-onlinemonitor[i].xmax[j])>=0.)
967 {
968 for(int k=0;k<(gSisData->wptr-1);k++)
969 {
970 now = clock2time(gSisData->sisClock[gSisData->wptr-1]);
971 datatime = clock2time(gSisData->sisClock[k]);
972 diff = datatime - now;
973 data = gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k];
974
975 //printf("i: %d, diff: %lf, data: %lf\n",i,diff,(double)data);
976
978 }
979 }
980
981 // Not all the data can fit in one histogram, so we don't have to loop over all the data
982
983 else
984 {
985 for(int k=(gSisData->wptr-(int)onlinemonitor[i].xmax[j]*1000);k<gSisData->wptr;k++)
986 {
987 if(k>0)
988 {
989 now = clock2time(gSisData->sisClock[gSisData->wptr-1]);
990 datatime = clock2time(gSisData->sisClock[k]);
991 diff = datatime - now;
992 data = gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k];
993
995 }
996 }
997 }
998 }
999
1000 // We've made a full loop around the data buffer so now there is data we want to look at both at the beginning and end of the buffer
1001
1002 else
1003 {
1004 if((clock2time(gSisData->sisClock[gSisData->wptr-1])-clock2time(gSisData->sisClock[0])-onlinemonitor[i].xmax[j])>=0.)
1005 {
1006 for(int k=0;k<gSisData->wptr;k++)
1007 {
1008 now = clock2time(gSisData->sisClock[gSisData->wptr-1]);
1009 datatime = clock2time(gSisData->sisClock[k]);
1010 diff = datatime - now;
1011 data = gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k];
1012
1014 }
1015 for(int k=(gSisData->wmax-(int)onlinemonitor[i].xmax[j]*1000+gSisData->wptr);k<(gSisData->wmax+1);k++)
1016 {
1017 now = clock2time(gSisData->sisClock[gSisData->wptr-1]);
1018 datatime = clock2time(gSisData->sisClock[k]);
1019 diff = datatime - now;
1020 uint32_t data = gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k];
1021
1023 }
1024 }
1025 else
1026 {
1027 for(int k=(gSisData->wptr-(int)onlinemonitor[i].xmax[j]*1000);k<gSisData->wptr;k++)
1028 {
1029 if(k>0)
1030 {
1031 now = clock2time(gSisData->sisClock[gSisData->wptr-1]);
1032 datatime = clock2time(gSisData->sisClock[k]);
1033 diff = now - datatime;
1034 uint32_t data = gSisData->sisChannels[onlinemonitor[i].histochannel[j]].sisData[k];
1035
1037 }
1038 }
1039 }
1040 }
1041 }
1042
1043 // Draw the histograms
1044
1045 if(j==0)
1046 {
1047 onlinemonitor[i].onlinehisto[j]->Draw();
1048 }
1049 else
1050 { // if the next histogram has larger values, expand the y range of the first
1051 if(onlinemonitor[i].onlinehisto[j]->GetMaximum()>onlinemonitor[i].onlinehisto[0]->GetMaximum())
1052 onlinemonitor[i].onlinehisto[0]->SetAxisRange(0,onlinemonitor[i].onlinehisto[j]->GetMaximum(),"Y");
1053 onlinemonitor[i].onlinehisto[j]->Draw("same");
1054 }
1055 }
1056 }
1057 printf("cptr: %d, wptr: %d, wmax: %d\n",gSisData->cptr,gSisData->wptr, gSisData->wmax);
1058
1059 gMainWindow->GetCanvas()->Modified();
1060 gMainWindow->GetCanvas()->Update();
1061 }
1062
1063 // Histogram the time between pulses
1064
1066 {
1067 double tfsdiff = 0;
1068
1069 if(!timefromsec)
1070 {
1071 timetestcanvas= new TCanvas("Time Between Signals","Time Between Signals");
1072 char name[80];
1073 sprintf(name,"Number of Seconds Between Signals, Channel %d, Run %d",gtestchannel,gRunNumber);
1074 timefromsec = new TH1D(name,name,20000,0,200);
1075 }
1076
1077 if((tptr<gSisData->wptr)&&(tptr<gSisData->wmax)) // when the read pointer is behind both the write pointer and max
1078 {
1079 while(tptr<gSisData->wptr) // send all the unchecked events to check against the switches
1080 {
1081 if(gSisData->sisChannels[gtestchannel].sisData[tptr]!=0)
1082 {
1083 if(tinit==false)
1084 {
1085 gtfs = clock2time(gSisData->sisClock[tptr]);
1086 tinit = true;
1087 }
1088 else
1089 {
1090 tfsdiff = clock2time(gSisData->sisClock[tptr])-gtfs;
1091 timefromsec->Fill(tfsdiff);
1092 gtfs = clock2time(gSisData->sisClock[tptr]);
1093 }
1094 }
1095 tptr++;
1096 }
1097 }
1098 else if ((tptr>gSisData->wptr)&&(tptr<gSisData->wmax)) // when the write pointer has gone back to zero, but the read pointer hasn't yet
1099 {
1100 while(tptr<gSisData->wmax)
1101 {
1102 if(gSisData->sisChannels[gtestchannel].sisData[tptr]!=0)
1103 {
1104 tfsdiff = clock2time(gSisData->sisClock[tptr])-gtfs;
1105 timefromsec->Fill(tfsdiff);
1106 gtfs = clock2time(gSisData->sisClock[tptr]);
1107 }
1108 tptr++;
1109 }
1110 }
1111 else if((tptr>gSisData->wptr)&&(tptr==gSisData->wmax)) // if the read pointer has readed the maximum (go back to zero)
1112 {
1113 tptr = 0;
1114 }
1115 timefromsec->Draw();
1116
1117 timetestcanvas->Modified();
1118 timetestcanvas->Update();
1119 }
1120}
1121
1122// To be run at the beginning of each run
1123
1125{
1126 //reset the SIS buffer
1127 gSisData->wptr=0;
1128 gSisData->wmax=0;
1129 gSisData->clock=0;
1130 gSisData->cptr=0;
1131
1132 tptr = 0;
1133 tinit = false;
1134
1135 //reset the switches
1136 for(int i=0;i<kMaxSwitches;i++)
1137 {
1138 switches[i].switchon=false;
1139 switches[i].keepgoing=true;
1141 }
1142
1143 //reset the number of switches
1144 numswitches=0;
1145 ReadSwitches(); //read in the new switches
1146}
1147
1148
1150{
1151 gOutputFile->cd("SIS");
1152 // Write the switches histograms if stopped in the middle
1153 for(int i=0;i<kMaxSwitches;i++)
1154 {
1155 if(switches[i].histo!=NULL)
1156 switches[i].histo->Write();
1157 }
1158
1159 // Write the pulse timing histograms
1161 {
1162 timetestcanvas->Write();
1163 timetestcanvas->Close();
1165 }
1166 gOutputFile->cd("../");
1167}
double xlabelsize
void resetClock2time()
const int ADchannel
double clock2time(uint64_t clock)
int xcanvas
int tptr
int dSISynoexponent
int dSISxpanels
void SISperiodic()
double textsize
bool mixingrecording
const int kNumOnlineHistos
TCanvas * timetestcanvas
void CheckDetails(int Channel, double counts, uint64_t clock)
double dSISylabeloffset
double detailsmin
const int kNumberofDetailChannels
double gtfs
TH1D * pbarhisto
char * DetailsTitles[kNumberofDetailChannels]
histopanel onlinemonitor[kNumPanels]
int numpanels
double ylabeloffset
int numswitches
int ypanels
void CheckMixingTriggers(int Channel, double counts, uint64_t clock)
TH1D * timefromsec
int dSISypanels
int pbarindex
bool mixingsequence
void SISEndRun()
SWITCH switches[kMaxSwitches]
double detailsmax
const double DetailsLength
TH1D * DetailsHisto[kNumberofDetailChannels]
int recordingstarttime
bool DetailsRecord[kNumberofDetailChannels]
int xpanels
int DetailsChannels[kNumberofDetailChannels]
void HandleSIS(int numChan, int size, const void *ptr)
void StepThroughSISBuffer()
double dSIStextsize
int Integral
int dSISycanvas
int mixingindex
void CheckTriggers(int Channel, double counts, uint64_t clock)
void ReadSwitches()
int dSISnumpanels
double detailsStartTime
bool pbarrecord
double dSISylabelsize
void CheckPbarTriggers(int Channel, double counts, uint64_t clock)
double ylabelsize
void SISBeginRun()
int ycanvas
int dSISxcanvas
int dumpnumber
bool tinit
int ynoexponent
double dSISxlabelsize
void onlineMonitorStart()
const int kNumPanels
TH1D * mixinghisto
bool pbarsequence
histopanel detailedSISmonitor[kNumPanels]
const int kMaxSwitches
INT channel
void * data
Definition mana.cxx:268
INT i
Definition mdump.cxx:32
#define name(x)
Definition midas_macro.h:24
INT j
Definition odbhist.cxx:40
INT k
Definition odbhist.cxx:40
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
int channeltoread
int switchtype
int startthr
int stopcounts
double start
int timescalled
bool switchon
double xmax
char title[80]
double xmin
int stopchannel
int eventcounts
TH1D * histo
int numstartevents
int startchannel
int numstopevents
int displaytype
int numbins
int stopthr
int startcounts
bool keepgoing
double xmax[kNumOnlineHistos]
char title[80]
int histochannel[kNumOnlineHistos]
int colour[kNumOnlineHistos]
TH1D * onlinehisto[kNumOnlineHistos]
double xmin[kNumOnlineHistos]
int nbins[kNumOnlineHistos]
int displaytype[kNumOnlineHistos]