1 /*******************************************************************************
2 * Copyright(c) 2003, IceCube Experiment at the South Pole. All rights reserved.
4 * Author: The IceCube RALICE-based Offline Project.
5 * Contributors are mentioned in the code where appropriate.
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation strictly for non-commercial purposes is hereby granted
9 * without fee, provided that the above copyright notice appears in all
10 * copies and that both the copyright notice and this permission notice
11 * appear in the supporting documentation.
12 * The authors make no claims about the suitability of this software for
13 * any purpose. It is provided "as is" without express or implied warranty.
14 *******************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////
20 // Conversion of Amanda raw TWR data into IceEvent data structures.
21 // The code to actually read the TWR raw data structures is an Ralice/IcePack
22 // implementation of Wolfgang Wagner's (Dortmund University, Germany)
23 // original read_twr_binary_file.cxx and wf2hit_new.cxx source code.
24 // The trigger information as encountered in the raw data, is available
25 // in the IceEvent structure via a device named "Trigger".
26 // The various triggers (and times) have been stored as different "hits"
27 // in this "Trigger" device, just like it was done in the IceF2k processor
28 // for the mu-daq F2K data.
29 // An indication of the active DAQ system is available in the IceEvent structure
30 // via a device named "Daq". Here the various daq systems (TWR, Muon, ...)
31 // from which the actual hits (ADC, LE, TOT) eventually will be composed
32 // are indicated as "signals" of the device itself.
33 // This class is derived from AliJob providing a task-based processing
34 // structure on an event-by-event basis.
35 // The main object in the job environment is an IceEvent* pointer.
36 // In case the user has provided sub-tasks, these will be executed
37 // on an event-by-event basis after the IceEvent structure has been filled
38 // with the raw TWR data and before the final structures are written out.
39 // Note that the data structures are only written out if an outputfile has
40 // been specified via the SetOutputFile memberfunction.
41 // In case no outputfile has been specified, this class provides a facility
42 // to investigate/analyse raw TWR data using the Ralice/IcePack analysis tools.
47 // gSystem->Load("ralice");
48 // gSystem->Load("icepack");
49 // gSystem->Load("iceconvert");
51 // IceRawTWR q("IceRawTWR","TWR raw data to IcePack data structure conversion");
53 // // Limit the number of entries for testing
54 // q.SetMaxEvents(10);
56 // // Print frequency to produce a short summary print every printfreq events
59 // // The TWR raw data input filename(s)
60 // q.AddInputFile("twr_2005_101_009225_0983_57784_57850.dat.twr.to_tape_1");
62 // // Output file for the event structures
63 // q.SetOutputFile("events.root");
65 // ///////////////////////////////////////////////////////////////////
66 // // Here the user can specify his/her sub-tasks to be executed
67 // // on an event-by-event basis after the IceEvent structure
68 // // has been filled and before the data is written out.
69 // // Sub-tasks (i.e. a user classes derived from TTask) are entered
72 // // MyXtalk task1("task1","Cross talk correction");
73 // // MyClean task2("task2","Hit cleaning");
77 // // The sub-tasks will be executed in the order as they are entered.
78 // ///////////////////////////////////////////////////////////////////
80 // // Perform the conversion and execute subtasks (if any)
81 // // on an event-by-event basis
84 //--- Author: Nick van Eijndhoven 12-dec-2006 Utrecht University
85 //- Modified: NvE $Date$ Utrecht University
86 ///////////////////////////////////////////////////////////////////////////
88 #include "IceRawTWR.h"
89 #include "Riostream.h"
91 ClassImp(IceRawTWR) // Class implementation to enable ROOT I/O
93 IceRawTWR::IceRawTWR(const char* name,const char* title) : AliJob(name,title)
95 // Default constructor.
96 // By default maxevent=-1, split=0, bsize=32000, printfreq=1.
105 ///////////////////////////////////////////////////////////////////////////
106 IceRawTWR::~IceRawTWR()
108 // Default destructor.
116 ///////////////////////////////////////////////////////////////////////////
117 void IceRawTWR::SetMaxEvents(Int_t n)
119 // Set the maximum number of events to be processed.
120 // n=-1 implies processing of the complete input file, which is the default
121 // initialisation in the constructor.
124 ///////////////////////////////////////////////////////////////////////////
125 void IceRawTWR::SetPrintFreq(Int_t f)
127 // Set the printfrequency to produce info every f events.
128 // f=1 is the default initialisation in the constructor.
129 if (f>=0) fPrintfreq=f;
131 ///////////////////////////////////////////////////////////////////////////
132 void IceRawTWR::SetSplitLevel(Int_t split)
134 // Set the split level for the ROOT data file.
135 // split=0 is the default initialisation in the constructor.
136 if (split>=0) fSplit=split;
138 ///////////////////////////////////////////////////////////////////////////
139 void IceRawTWR::SetBufferSize(Int_t bsize)
141 // Set the buffer size for the ROOT data file.
142 // bsize=32000 is the default initialisation in the constructor.
143 if (bsize>=0) fBsize=bsize;
145 ///////////////////////////////////////////////////////////////////////////
146 void IceRawTWR::AddInputFile(TString name)
148 // Add the name of this TWR raw data input file to the list to be processed.
152 fInfiles=new TObjArray();
153 fInfiles->SetOwner();
156 TObjString* s=new TObjString();
160 ///////////////////////////////////////////////////////////////////////////
161 void IceRawTWR::SetOutputFile(TFile* ofile)
163 // Set the output file for the ROOT data.
164 if (fOutfile) delete fOutfile;
167 ///////////////////////////////////////////////////////////////////////////
168 void IceRawTWR::SetOutputFile(TString name)
170 // Create the output file for the ROOT data.
171 if (fOutfile) delete fOutfile;
172 fOutfile=new TFile(name.Data(),"RECREATE","TWR raw data in IceEvent structure");
174 ///////////////////////////////////////////////////////////////////////////
175 TFile* IceRawTWR::GetOutputFile()
177 // Provide pointer to the ROOT output file.
180 ///////////////////////////////////////////////////////////////////////////
181 void IceRawTWR::Exec(Option_t* opt)
183 // Job to loop over the specified number of events and convert the
184 // TWR raw data into the IceEvent structure.
185 // If maxevents<0 (default) all the entries of the input file
186 // will be processed.
187 // Every "printfreq" events a short event summary will be printed.
188 // The default value is printfreq=1.
189 // The output will be written on a standard output tree named "T".
193 // 1) This class is derived from AliJob, allowing a task based processing.
194 // After the conversion of a raw data event into an IceEvent structure,
195 // the processing of all available sub-tasks (if any) is invoked.
196 // This provides an event-by-event (sub)task processing before the
197 // final data structures are written out.
198 // 2) The main object in this job environment is an IceEvent* pointer.
202 cout << " *IceRawTWR Exec* No data input file(s) specified." << endl;
206 Int_t ninfiles=fInfiles->GetEntries();
209 cout << " *IceRawTWR Exec* No data input file(s) specified." << endl;
216 otree=new TTree("T","TWR raw data converted to IceEvent structures");
217 otree->SetDirectory(fOutfile);
220 IceEvent* evt=new IceEvent();
221 evt->SetTrackCopy(1);
224 // Branch in the tree for the event structure
225 if (otree) otree->Branch("IceEvent","IceEvent",&evt,fBsize,fSplit);
227 // Initialise the job working environment
237 cout << " ***" << endl;
238 cout << " *** Start processing of job " << GetName() << " ***" << endl;
239 cout << " ***" << endl;
240 for (Int_t i=0; i<ninfiles; i++)
242 TObjString* sx=(TObjString*)fInfiles->At(i);
244 inputfile=sx->GetString();
245 cout << " TWR raw data input file : " << inputfile.Data() << endl;
247 cout << " Maximum number of events to be processed : " << fMaxevt << endl;
248 cout << " Print frequency : " << fPrintfreq << endl;
251 cout << " ROOT output file : " << fOutfile->GetName() << endl;
252 cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
257 // Storage of the used parameters in the IceRawTWR device
259 params.SetNameTitle("IceRawTWR","IceRawTWR processor parameters");
260 params.SetSlotName("Nchannels",1);
261 params.SetSlotName("Ntriggers",2);
262 params.SetSlotName("BaselineOffset",3);
263 params.SetSlotName("NanosecsPerTWRbin",4);
264 params.SetSignal(float(N_OF_CHANNELS),1);
265 params.SetSignal(float(N_OF_TRIGGERS),2);
266 params.SetSignal(float(BASELINE_MEAN_MAGIC),3);
267 params.SetSignal(float(NSECS_PER_TWR_BIN),4);
269 // Set DAQ device info
272 daq.SetSlotName("TWR",1);
275 twr_raw_data_file_t twr_file;
276 Int_t year,runnum,evtnum;
282 UInt_t gpslow,gpshigh,gpssecs; // The GPS time information
283 Int_t seconds,nsecs; // Seconds and nanoseconds since start of the UT year
287 for (Int_t ifile=0; ifile<ninfiles; ifile++)
289 TObjString* sx=(TObjString*)fInfiles->At(ifile);
292 inputfile=sx->GetString();
293 if (inputfile=="") continue;
295 // Open the TWR raw data input file in binary mode
296 fInput=fopen(inputfile.Data(),"rb");
300 cout << " *IceRawTWR Exec* No input file found with name : " << inputfile.Data() << endl;
304 // Extract info like run number, file number etc... from filename
305 extract_info_from_filename((char*)inputfile.Data(),&twr_file);
308 runnum=twr_file.run_no;
310 // Initialise the event structure
311 clear_event(&fEvent);
313 // Read the file header information
314 error=read_header_from_file(fInput,&fHeader,&nhead);
318 cout << " *IceRawTWR Exec* Error in header for input file : " << inputfile.Data() << endl;
322 // Correct the mapping
323 update_system(fHeader,runnum);
325 // Retrieve the actual readout system, threshold and external stop of each OM for these data
329 Int_t ncrates=fHeader->n_crates;
331 Int_t omid,readout,thresh,extstop;
332 for (Int_t icr=0; icr<ncrates; icr++)
334 ntwrs=fHeader->crate[icr]->n_twr;
335 for (Int_t i_twr=0; i_twr<ntwrs; i_twr++)
337 extstop=fHeader->crate[icr]->twr[i_twr]->ext_stop;
338 for (Int_t ich=0; ich<CHANNELS_PER_TWR; ich++)
340 omid=fHeader->crate[icr]->twr[i_twr]->om_no[ich];
341 thresh=fHeader->crate[icr]->twr[i_twr]->threshold[ich];
342 readout=1+fHeader->crate[icr]->twr[i_twr]->om_is_optical[ich];
343 if (omid>=0 && omid<=681)
345 fReadout.AddAt(readout,omid-1);
346 fThreshold.AddAt(thresh,omid-1);
347 fExtstop.AddAt(extstop,omid-1);
353 while (!read_event(fInput,fHeader,&fEvent))
355 if (fMaxevt>-1 && nevt>=fMaxevt) break;
357 evtnum=fEvent.eventcounter;
359 // The GPS telegram info
361 gpslow=gps.seconds & 0x00FFFFFF; // The low 24 bits of the seconds count
362 gpshigh=gps.info.bits.seconds; // The high 8 bits of the seconds count
366 // Seconds and nanoseconds since the start of the UT year
368 nsecs=100*gps.count_10MHz;
370 // Correction for GPS telegram interpretation in the TWR Daq
371 if (year<2007) seconds-=24*3600;
373 // Reset the complete Event structure
376 evt->SetRunNumber(runnum);
377 evt->SetEventNumber(evtnum);
378 evt->SetUT(year,0,seconds,nsecs);
380 evt->AddDevice(params);
387 // Invoke all available sub-tasks (if any)
393 if (!(nevt%fPrintfreq)) evt->HeaderData();
396 // Write the complete structure to the output Tree
397 if (otree) otree->Fill();
399 // Update event counter
402 // Reset the raw event structure
403 clear_event(&fEvent);
404 } // End of event reading loop
406 // Delete the file header structure
407 clear_system(fHeader);
409 if (fMaxevt>-1 && nevt>=fMaxevt) break;
411 } // End of input file loop
413 // Flush possible memory resident data to the output file
414 if (fOutfile) fOutfile->Write();
416 // Remove the IceEvent object from the environment
417 // and delete it as well
424 ///////////////////////////////////////////////////////////////////////////
425 void IceRawTWR::PutWaveforms(Int_t year)
427 // Get the waveform info from the raw data event into the IcePack structure.
429 IceEvent* evt=(IceEvent*)GetMainObject();
432 // Get trigger time for TWR time reference
434 AliDevice* trig=(AliDevice*)evt->GetDevice("Trigger");
437 AliSignal* sx=trig->GetHit("main");
438 if (sx) trigtime=sx->GetSignal("trig_pulse_le");
441 // Loop over all the waveforms and add the histo(s) to the corresponding OM's
454 Int_t firstbin,lastbin;
456 for (Int_t i=0; i<N_OF_CHANNELS; i++)
458 if (!fEvent.wfm_filled[i]) continue;
461 if (omid<=0 || omid>omidmax) continue; // Skip trigger channels
463 // Get corresponding device from the current event structure
464 omx=(IceAOM*)evt->GetIdDevice(omid);
468 om.SetUniqueID(omid);
470 omx=(IceAOM*)evt->GetIdDevice(omid);
475 extstop=fExtstop.At(omid-1);
477 // Update readout type and threshold for this OM
478 omx->AddNamedSlot("READOUT");
479 omx->SetSignal(float(fReadout.At(omid-1)),"READOUT");
480 omx->AddNamedSlot("THRESH");
481 omx->SetSignal(float(fThreshold.At(omid-1)),"THRESH");
482 omx->AddNamedSlot("EXTSTOP");
483 omx->SetSignal(float(extstop),"EXTSTOP");
485 clear_waveform_analysis(&fWform);
486 error=restore_waveform(fEvent.wfm[i],&fWform,year);
490 nfrags=fWform.n_frag;
492 for (Int_t ifrag=0; ifrag<nfrags; ifrag++)
494 baseline=fWform.frag_mean[ifrag];
497 hname+=omx->GetNwaveforms()+1;
498 omx->AddNamedSlot(hname);
499 omx->SetSignal(baseline,hname);
501 // Fill the waveform histogram with this fragment
505 hname+=omx->GetNwaveforms()+1;
508 histo.SetName(hname.Data());
509 nbins=fWform.frag_n_points[ifrag];
510 firstbin=fWform.frag_begin[ifrag];
511 lastbin=fWform.frag_end[ifrag];
513 xlow=fWform.wfm_x[firstbin];
514 xup=fWform.wfm_x[lastbin];
516 // Synchronise waveform times with external stop and trigger time
517 xlow=xlow-float(NSECS_PER_TWR_BIN)*(1024-extstop)+trigtime;
518 xup=xup-float(NSECS_PER_TWR_BIN)*(1024-extstop)+trigtime;
520 histo.SetBins(nbins,xlow,xup);
522 for (Int_t jbin=1; jbin<=nbins; jbin++)
524 histo.SetBinContent(jbin,baseline-fWform.wfm_y[firstbin+jbin-1]);
527 omx->SetWaveform(&histo,omx->GetNwaveforms()+1);
528 } // End of loop over fragments of this OM
529 } // End of loop over channels
531 ///////////////////////////////////////////////////////////////////////////
532 void IceRawTWR::PutTrigger(Int_t year)
534 // Get the trigger info from the raw data event into the IcePack structure.
535 // Currently only the trigger settings for the years 2005 and 2006 have been
537 // In addition to the hardware and software triggers as encountered in the
538 // raw data, an artificial "main" trigger has been introduced.
539 // This artificial "main" trigger is just an "or" of the standard hard and soft
540 // triggers (except calibration and random triggers) and serves only to
541 // provide a generic "main" trigger a la Amanda mu-daq so that the default
542 // "IceCleanHits" hit cleaning procedure will work correctly.
543 // The trigger time for the artificial "main" trigger is taken to be the
544 // time of the earliest hardware trigger pulse. In case there is no hardware
545 // trigger pulse available, the "main" trigger time is set to 0.
546 // For other years, only the artificial "main" trigger with a trigger time
547 // set to 0 will be stored in the IceEvent structure.
549 // Fill the trigger structure
550 Int_t error=retrigger(&fEvent,&fTrigger);
553 IceEvent* evt=(IceEvent*)GetMainObject();
557 trig.SetNameTitle("Trigger","Amanda/IceCube event triggers");
561 if (year !=2005 && year != 2006)
564 s.SetTitle("First trigger for TWR time reference");
566 s.SetSlotName("trig_pulse_le",1);
567 s.SetSignal(trigtime,1);
569 // Store the trigger data into the IceEvent structure
570 evt->AddDevice(trig);
574 // Trigger settings for 2005 and 2006
575 if (!fTrigger.n_software_trigger && !fTrigger.n_hardware_trigger) return;
577 TString trignames[N_OF_TRIGGERS]={"m24","m18","string","spase","cal-t0","cal-la","m12",
578 "main-logic","main-or","random","m20-frag","volume"};
580 for (Int_t i=0; i<N_OF_TRIGGERS; i++)
582 if (!fTrigger.trigger_active[i]) continue;
585 s.SetName(trignames[i]);
588 if (fTrigger.trigger_has_pulse[i]) trigtime=float(fTrigger.trigger_time[i]*NSECS_PER_TWR_BIN);
589 s.SetSlotName("trig_pulse_le",1);
590 s.SetSignal(trigtime,1);
592 // Set flag to indicate creation of artificial "main" trigger
593 if (i!=4 && i!=5 && i!=9) imain=1;
596 // Set the artificial "main" trigger to indicate the first trigger signal
601 s.SetTitle("First trigger for TWR time reference");
602 s.SetUniqueID(N_OF_TRIGGERS);
603 s.SetSlotName("trig_pulse_le",1);
605 if (fTrigger.first_trigger>=0) trigtime=float(fTrigger.first_trigger_time*NSECS_PER_TWR_BIN);
606 s.SetSignal(trigtime,1);
610 // Store the trigger data into the IceEvent structure
611 evt->AddDevice(trig);
613 ///////////////////////////////////////////////////////////////////////////
614 Int_t IceRawTWR::extract_info_from_filename(char* fname,twr_raw_data_file_t* twr_file)
616 char start_str[20],year_str[20],day_str[20],run_no_str[20],
617 file_no_str[20],begin_str[20],end_str[20];
620 filename = strstr(fname, "twr");
622 if(strncmp("twr_", start_str, 4))
624 printf("%s\n", filename);
625 return(ERROR_NOT_VALID_FILENAME);
628 strncpy(start_str, filename, 4);
629 if(strncmp("twr_", start_str, 4))
631 printf("%s %s\n", filename, start_str);
632 return(ERROR_NOT_VALID_FILENAME);
634 strncpy(year_str, &filename[4], 4);
635 twr_file->year = strtol(year_str, 0, 10);
637 if(twr_file->year==2003)
639 strncpy(day_str, &filename[9], 3);
641 twr_file->day = strtol(day_str, 0, 10);
643 strncpy(run_no_str, &filename[13], 4);
644 run_no_str[4] = '\0';
645 twr_file->run_no = strtol(run_no_str, 0, 10);
647 strncpy(file_no_str, &filename[18], 4);
648 file_no_str[4] = '\0';
649 twr_file->file_no = strtol(file_no_str, 0, 10);
652 if(twr_file->year==2004)
654 strncpy(day_str, &filename[9], 3);
656 twr_file->day = strtol(day_str, 0, 10);
658 strncpy(run_no_str, &filename[13], 4);
659 run_no_str[4] = '\0';
660 twr_file->run_no = strtol(run_no_str, 0, 10);
662 strncpy(file_no_str, &filename[18], 4);
663 file_no_str[4] = '\0';
664 twr_file->file_no = strtol(file_no_str, 0, 10);
666 strncpy(begin_str, &filename[23], 5);
668 twr_file->begin = strtol(begin_str, 0, 10);
670 strncpy(end_str, &filename[29], 5);
672 twr_file->end = strtol(end_str, 0, 10);
675 if(twr_file->year > 2004)
677 strncpy(day_str, &filename[9], 3);
679 twr_file->day = strtol(day_str, 0, 10);
681 strncpy(run_no_str, &filename[13], 6);
682 run_no_str[6] = '\0';
683 twr_file->run_no = strtol(run_no_str, 0, 10);
685 strncpy(file_no_str, &filename[20], 4);
686 file_no_str[4] = '\0';
687 twr_file->file_no = strtol(file_no_str, 0, 10);
689 strncpy(begin_str, &filename[25], 5);
691 twr_file->begin = strtol(begin_str, 0, 10);
693 strncpy(end_str, &filename[31], 5);
695 twr_file->end = strtol(end_str, 0, 10);
699 ///////////////////////////////////////////////////////////////////////////
700 Int_t IceRawTWR::clear_system(sys_config_t* sys)
702 // Deletion of the file header structure.
706 for(Int_t icrate=0; icrate < int(sys->n_crates); icrate++)
708 if (!sys->crate[icrate]) continue;
709 for(Int_t itwr=0; itwr < int(sys->crate[icrate]->n_twr); itwr++)
711 if (sys->crate[icrate]->twr[itwr]) delete sys->crate[icrate]->twr[itwr];
713 delete sys->crate[icrate];
719 ///////////////////////////////////////////////////////////////////////////
720 Int_t IceRawTWR::clear_event(event_t* event_ptr)
723 Int_t *int_ptr = (int*) event_ptr;
725 for(i_value=0; i_value < int(sizeof(event_t)/sizeof(Int_t)); i_value++)
731 ///////////////////////////////////////////////////////////////////////////
732 Int_t IceRawTWR::read_header_from_file(FILE* fin,sys_config_t** system_ptr,UInt_t* header_length)
734 Int_t i_crate, i_twr, i_channel;
735 UInt_t count_twr_in_system = 0;
740 // allocating memory for sys_config structure
741 sys = (sys_config_t*) malloc( sizeof(sys_config_t) );
743 fread(&dummy,sizeof(UInt_t),1,fin); // Header Begin Mark
745 fread(header_length,sizeof(UInt_t),1,fin); // Length of header
746 fread(&sys->clockdiv,sizeof(UInt_t),1,fin);
747 fread(&sys->n_crates,sizeof(UInt_t),1,fin);
749 if( (sys->n_crates > MAX_N_CRATES) || (sys->n_crates < 0) )
750 return(ERROR_TOO_MANY_CRATES);
752 for(i_crate=0; i_crate < int(sys->n_crates); i_crate++)
754 sys->crate[i_crate] =
755 (crate_config_t*) malloc( sizeof(crate_config_t) );
757 fread(&sys->crate[i_crate]->vme_base_bridge,sizeof(UInt_t),1,fin);
758 fread(&sys->crate[i_crate]->vme_base_100MHz,sizeof(UInt_t),1,fin);
759 fread(&sys->crate[i_crate]->base_gps,sizeof(UInt_t),1,fin);
760 fread(&sys->crate[i_crate]->n_twr,sizeof(UInt_t),1,fin);
762 if( (sys->crate[i_crate]->n_twr > MAX_N_TWR_PER_CRATE)
763 || (sys->crate[i_crate]->n_twr < 0) )
764 return(ERROR_TOO_MANY_TWRS);
766 for(i_twr=0; i_twr < int(sys->crate[i_crate]->n_twr); i_twr++)
768 sys->crate[i_crate]->twr[i_twr] =
769 (twr_config_t*) malloc( sizeof(twr_config_t) );
770 count_twr_in_system++;
771 fread(&sys->crate[i_crate]->twr[i_twr]->base,
772 sizeof(UInt_t),1,fin);
773 fread(&sys->crate[i_crate]->twr[i_twr]->id,
774 sizeof(UInt_t),1,fin);
776 sys->crate[i_crate]->twr[i_twr]->id
777 = sys->crate[i_crate]->twr[i_twr]->id - 0x10; /* Correct */
780 fread(&dummy,sizeof(UInt_t),1,fin); /* stat_reg */
781 fread(&sys->crate[i_crate]->twr[i_twr]->mod_id,
782 sizeof(UInt_t),1,fin);
783 fread(&dummy,sizeof(UInt_t),1,fin); /* acq_ctrl */
784 fread(&sys->crate[i_crate]->twr[i_twr]->ext_start,
785 sizeof(UInt_t),1,fin);
786 fread(&sys->crate[i_crate]->twr[i_twr]->ext_stop,
787 sizeof(UInt_t),1,fin);
788 fread(&dummy,sizeof(UInt_t),1,fin); /* evtconfig */
790 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
792 fread(&sys->crate[i_crate]->twr[i_twr]->om_no[i_channel],
793 sizeof(UInt_t),1,fin);
796 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
798 fread(&sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel],
799 sizeof(UInt_t),1,fin);
802 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
804 fread(&sys->crate[i_crate]->twr[i_twr]->baseline[i_channel],
805 sizeof(UInt_t),1,fin);
808 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
810 fread(&sys->crate[i_crate]->twr[i_twr]->threshold[i_channel],
811 sizeof(UInt_t),1,fin);
814 sys->twr_field[(i_crate * 0x10) + i_twr]
815 = sys->crate[i_crate]->twr[i_twr];
818 for(i_channel=0; i_channel < 8; i_channel++)
820 if( sys->crate[i_crate]->twr[i_twr]->om_no[i_channel] == 9000 )
821 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]
827 // Set number of TWRs in system
828 sys->n_twr = count_twr_in_system;
833 ///////////////////////////////////////////////////////////////////////////
834 Int_t IceRawTWR::update_system(sys_config_t* sys,Int_t run_number)
836 Int_t i_crate, i_twr, i_channel;
838 // Data for bug fix 1 by Andreas
839 UInt_t om_no_r1[CHANNELS_PER_TWR]
840 = {111, 112, 113, 114, 115, 116, 39, 118};
841 UInt_t om_is_optical_r1[CHANNELS_PER_TWR]
842 = {0, 0, 0, 0, 0, 0, 0, 0};
843 UInt_t threshold_r1[CHANNELS_PER_TWR]
844 = {50, 50, 50, 50, 50, 50, 80, 50};
846 // Data for bugfix 2 by Timo
847 UInt_t om_no_r2[CHANNELS_PER_TWR]
848 = {473, 484, 485, 486, 487, 475, 490, 491};
849 UInt_t om_is_optical_r2[CHANNELS_PER_TWR]
850 = {1, 1, 1, 1, 1, 1, 1, 1};
851 UInt_t threshold_r2[CHANNELS_PER_TWR]
852 = {15, 50, 55, 40, 15, 23, 15, 15};
854 // Data for bugfix 3 by Wolfgang
855 // Old (=incorrect) OM config : {183, 184, 185, 38, 187, 188, 189, 190}
856 UInt_t om_no_r3[CHANNELS_PER_TWR]={345, 184, 185, 38, 187, 188, 189, 190};
857 UInt_t om_is_optical_r3[CHANNELS_PER_TWR]={1, 0, 0, 0, 0, 0, 0, 0};
858 UInt_t threshold_r3[CHANNELS_PER_TWR]={20, 50, 50, 80, 50, 50, 50, 50};
860 // Old (=incorrect) OM config : {345, 346, 454, 450, 635, 10000, 10000, 10000}
861 UInt_t om_no_r4[CHANNELS_PER_TWR]={183, 346, 454, 450, 635, 10000, 10000, 10000};
862 UInt_t om_is_optical_r4[CHANNELS_PER_TWR]={0, 1, 1, 1, 1, 1, 1, 1};
863 UInt_t threshold_r4[CHANNELS_PER_TWR]={50, 20, 20, 20, 20, 500, 500, 500};
865 // Bugfix 1 Andreas Bug
867 // By accident this TWR was counted twice in TWR.cnf
868 // as Crate 0 TWR 7 and Crate 4 TWR 7
869 // from run 9153 up to run 9841 (incl.)
870 // TWR_OM 639 642 1 9 10 11 12 30
871 // OPTICAL 0 0 0 0 0 0 0 0
872 // TWR_BASELINE 110 120 110 140 150 160 170 180
873 // TWR_THRESHOLD 50 50 80 80 80 80 80 80
875 // Crate 4 TWR 7 should be replaced with this TWR
876 // TWR_OM 111 112 113 114 115 116 39 118
877 // OPTICAL 0 0 0 0 0 0 0 0
878 // TWR_BASELINE 110 120 130 140 150 160 170 180
879 // TWR_THRESHOLD 50 50 50 50 50 50 80 50
881 // Begin season 2005 13-feb-2005
882 // Timo corrected TWR.cnf on 05-apr-2006 after run 9841
883 if (run_number>=9153 && run_number<=9841)
887 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
889 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r1[i_channel];
890 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r1[i_channel];
891 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r1[i_channel];
895 // Bugfix 2 Timos Bug
897 // By accident this TWR was counted twice in TWR.cnf
898 // as Crate 0 TWR 1 and Crate 5 TWR b
899 // from run 9153 up to run 9188 (incl.)
901 // TWR_OM 492 493 495 496 497 499 500 501
902 // OPTICAL 1 1 1 1 1 1 1 1
903 // TWR_BASELINE 110 120 130 140 150 160 170 180
904 // TWR_THRESHOLD 16 45 25 42 35 46 15 15
906 // Crate 5 TWR b should be corrected to
907 // TWR_OM 473 484 485 486 487 475 490 491
908 // OPTICAL 1 1 1 1 1 1 1 1
909 // TWR_BASELINE 4000 120 130 140 150 4000 170 180
910 // TWR_THRESHOLD 15 50 55 40 15 23 15 15
912 // Begin season 2005 : 13-feb-2005
913 // Timo corrected TWR.cnf on 15-mar-2005 (= day 74) after run 9188
914 if (run_number>=9153 && run_number<=9188)
918 for(i_channel=0; i_channel<CHANNELS_PER_TWR; i_channel++)
920 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r2[i_channel];
921 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r2[i_channel];
922 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r2[i_channel];
926 // Bugfix 3 by Wolfgang Wagner : Mismatch of OM 345 and 183
927 // Begin season 2005 : 13-feb-2005
928 // Wolfgang corrected TWR.cnf on 15-aug-2005 after run 9988
929 if (run_number>=9153 && run_number<=9988)
933 for(i_channel=0; i_channel<CHANNELS_PER_TWR; i_channel++)
935 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r3[i_channel];
936 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r3[i_channel];
937 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r3[i_channel];
941 for(i_channel=0; i_channel<CHANNELS_PER_TWR; i_channel++)
943 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r4[i_channel];
944 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r4[i_channel];
945 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r4[i_channel];
951 ///////////////////////////////////////////////////////////////////////////
952 Int_t IceRawTWR::read_event(FILE* fin,sys_config_t* sys,event_t* event_ptr)
955 UInt_t length_of_event_block;
957 Int_t n_twr, n_of_waveforms_in_event, read_number;
958 UInt_t length_wfm[CHANNELS_PER_TWR];
959 UInt_t dummy, channel_no, om_no, twr_no;
961 // Reset waveform filled register
962 memset(&event_ptr->wfm_filled[0], 0, sizeof(UInt_t) * N_OF_CHANNELS);
964 if( !fread(&dummy,sizeof(UInt_t),1,fin) ) return(1);
966 if(dummy != 0xbbbbbbbb)
968 printf("Wrong event begin mark %x\n", dummy);
969 while( (dummy !=0xbbbbbbbb)
970 && (fread(&dummy,sizeof(UInt_t),1,fin) != 0) )
971 {;//printf("dummy:%x\n", dummy);
974 if( !fread(&length_of_event_block,sizeof(UInt_t),1,fin) ) return(1);
975 if( !fread(&event_ptr->eventcounter,sizeof(UInt_t),1,fin) ) return(1);
976 if( !fread(&event_ptr->which_trigger,sizeof(UInt_t),1,fin) ) return(1);
977 if( !fread(&event_ptr->gps,sizeof(GPS_t),1,fin) ) return(1);
979 // --reading waveforms from TWR blocks
981 while(n_twr < int(sys->n_twr))
984 if( !fread(&dummy,sizeof(UInt_t),1,fin) ) return(1);
985 if(dummy != 0xffffffff)
986 {printf("Wrong twr begin mark %x\n", dummy); return(2);}
987 if( !fread(&twr_no,sizeof(UInt_t),1,fin) ) return(1);
989 // nur voruebergehend !!
992 if( !fread(&event_ptr->twr[twr_no].timestamp,sizeof(UInt_t),1,fin) )
994 if( !fread(&n_of_waveforms_in_event,sizeof(UInt_t),1,fin) )
996 event_ptr->twr[twr_no].n_wfm = n_of_waveforms_in_event;
998 for(i_wfm=0; i_wfm < n_of_waveforms_in_event; i_wfm++)
1000 if( !fread(&length_wfm[i_wfm],sizeof(UInt_t),1,fin) ) return(1);
1004 for(i_wfm=0; i_wfm < n_of_waveforms_in_event; i_wfm++)
1006 if(length_wfm[i_wfm] != 0)
1008 if( !fread(&channel_no,sizeof(UInt_t),1,fin) ) return(1);
1009 if(sys->twr_field[twr_no]->om_no[channel_no]
1011 om_no = sys->twr_field[twr_no]->om_no[channel_no];
1013 om_no = N_OF_CHANNELS-1;
1017 event_ptr->twr_id_of_om[om_no] = twr_no;
1019 read_number = fread(&event_ptr->wfm[om_no],
1020 length_wfm[i_wfm]-sizeof(UInt_t),1,fin);
1021 event_ptr->wfm_filled[om_no] = 1;
1022 if( !read_number ) return(1);
1024 // read_number correction for usage of fread() instead of read()
1025 read_number*=length_wfm[i_wfm]-sizeof(UInt_t);
1027 if( read_number != int(length_wfm[i_wfm]-sizeof(UInt_t)) )
1029 cout << " read_number : " << read_number
1030 << " length_wfm["<<i_wfm<<"] : " << length_wfm[i_wfm]
1031 << " sizeof(UInt_t) : " << sizeof(UInt_t) << endl;
1037 } // end while n_twr
1040 ///////////////////////////////////////////////////////////////////////////
1041 Int_t IceRawTWR::retrigger(event_t* ev,trigger_hits_t* trig)
1043 // Returns the active trigger(s)
1045 // Initialise the trigger_hits_t structure with zeroes
1046 memset(trig, 0, sizeof(trigger_hits_t) );
1048 // Obtain the software trigger info
1049 trig->n_software_trigger=0;
1050 for(Int_t itrigger=0; itrigger<N_OF_TRIGGERS; itrigger++)
1052 if(ev->which_trigger & trigger_bits[itrigger])
1054 //printf("SetTrigger %i\n", i_trigger);
1055 trig->trigger_active[itrigger]=1;
1056 trig->n_software_trigger++;
1060 trig->trigger_active[itrigger]=0;
1064 // Obtain the hardware trigger info
1065 trig->n_hardware_trigger=0;
1066 trig->first_trigger_time=10000000;
1067 trig->first_trigger=-1;
1069 for(Int_t jtrigger=0; jtrigger<N_OF_TRIGGERS; jtrigger++)
1071 if(!trigger_channel[jtrigger]) continue;
1073 if(ev->wfm_filled[trigger_channel[jtrigger]])
1075 trig->trigger_active[jtrigger]=1;
1076 trig->trigger_time[jtrigger]=(ev->wfm[trigger_channel[jtrigger]].value[2] & 0xfff);
1077 trig->trigger_has_pulse[jtrigger]=1;
1078 if (trig->trigger_time[jtrigger] < trig->first_trigger_time)
1080 trig->first_trigger_time=trig->trigger_time[jtrigger];
1081 trig->first_trigger=jtrigger;
1083 trig->n_hardware_trigger++;
1088 ///////////////////////////////////////////////////////////////////////////
1089 Int_t IceRawTWR::clear_waveform_analysis(waveform_analyse_t* wfm_om)
1091 Int_t i_value, i_frag, i_edge, i_peak;
1093 if(wfm_om == 0) return(1);
1095 // output from analysis
1097 for(i_frag=0; i_frag < MAX_N_OF_FRAGS; i_frag++)
1099 wfm_om->frag_n_points[i_frag] = 0;
1100 wfm_om->frag_begin[i_frag] = 0;
1101 wfm_om->frag_end[i_frag] = 0;
1102 wfm_om->frag_mean[i_frag] = 0;
1103 wfm_om->frag_begin_time[i_frag] = 0;
1107 for(i_peak=0; i_peak < MAX_N_OF_PEAKS; i_peak++)
1109 wfm_om->peak_begin[i_peak] = 0;
1110 wfm_om->peak_end[i_peak] = 0;
1111 wfm_om->peak_max[i_peak] = 0;
1112 wfm_om->peak_TDC_edge[i_peak] = 0;
1113 wfm_om->peak_local_minimum[i_peak] = 0;
1114 wfm_om->crosstalk_charge_n_value[i_peak] = 0;
1115 wfm_om->peak_in_fragment[i_peak] = 0;
1117 wfm_om->peak_mean[i_peak] = 0.0;
1119 wfm_om->peak_m[i_peak] = 0.0;
1120 wfm_om->peak_b[i_peak] = 0.0;
1121 wfm_om->peak_t0[i_peak] = 0.0;
1122 wfm_om->peak_begin_time[i_peak] = 0.0;
1123 wfm_om->peak_charge[i_peak] = 0.0;
1124 wfm_om->peak_height[i_peak] = 0.0;
1125 wfm_om->fitted_amplitude[i_peak] = 0.0;
1126 wfm_om->fitted_TOT[i_peak] = 0.0;
1127 wfm_om->crosstalk_charge[i_peak] = 0.0;
1128 wfm_om->crosstalk_slope[i_peak] = 0.0;
1131 wfm_om->n_point = 0;
1132 wfm_om->wfm_min = 4095;
1133 wfm_om->wfm_max = 0;
1134 wfm_om->b_out_of_range = 0;
1136 for(i_value=0; i_value < 1024; i_value++)
1138 wfm_om->wfm_x[i_value] = 0;
1139 wfm_om->wfm_y[i_value] = 0;
1142 wfm_om->n_tdc_edges = 0;
1143 for(i_edge=0; i_edge < MAX_N_OF_TDC_EDGES; i_edge++)
1145 wfm_om->leading_edge[i_edge] = 0.0;
1146 wfm_om->falling_edge[i_edge] = 0.0;
1147 wfm_om->identified_twr_hit[i_edge] = -1;
1152 ///////////////////////////////////////////////////////////////////////////
1153 Int_t IceRawTWR::restore_waveform(waveform_t f_wfm,waveform_analyse_t* wfm_om,Int_t year)
1155 UShort_t wfm_length, mean;
1156 static UShort_t tmp_wf[2000];
1159 Int_t fragment_start = 0;
1160 Int_t frag_count = 0; // position in current fragment
1161 Int_t n_position = 0; // position in displayed waveform
1162 UInt_t n_word = 2; // position in featured waveform
1163 Int_t n_fragment = 0; // actual fragment
1164 Int_t b_wrong_value = 0;
1166 UShort_t assumed_frag_begin, last_value; /* bug in eventbuilder */
1168 wfm_om->wfm_min = 4095.0;
1169 wfm_om->wfm_max = 0.0;
1171 if( (f_wfm.value[0] & 0xf000) != 0xf000 ) return(1);
1172 wfm_length = (f_wfm.value[0] & 0xfff)/2;
1174 mean = f_wfm.value[1] + BASELINE_MEAN_MAGIC;
1175 while( ((f_wfm.value[n_word] & 0xf000) == 0x4000) &&
1176 (n_word < wfm_length) &&
1177 (n_fragment < MAX_N_OF_FRAGS) )
1179 fragment_start = f_wfm.value[n_word] & 0xfff;
1181 wfm_om->frag_begin_time[n_fragment]
1182 = fragment_start * NSECS_PER_TWR_BIN;
1183 wfm_om->frag_begin[n_fragment] = n_position;
1184 wfm_om->frag_mean[n_fragment] = mean;
1189 while( ((f_wfm.value[n_word] & 0xf000) != 0x2000) &&
1190 ((f_wfm.value[n_word] & 0xf000) != 0x4000) &&/*Reconstructable*/
1191 !b_wrong_value && /* Buggy */
1192 (n_word < wfm_length) )
1196 /* 2005 2006 data */
1199 tmp_wf[n_word] = f_wfm.value[n_word] + mean;
1200 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1201 wfm_om->wfm_x[n_position] = (float)
1202 wfm_om->frag_begin_time[n_fragment]
1203 + (frag_count * NSECS_PER_TWR_BIN);
1205 else if(frag_count == 1)
1207 tmp_wf[n_word] = f_wfm.value[n_word] + tmp_wf[n_word-1];
1208 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1209 wfm_om->wfm_x[n_position] = (float)
1210 wfm_om->frag_begin_time[n_fragment]
1211 + (frag_count * NSECS_PER_TWR_BIN);
1216 2*tmp_wf[n_word-1] + f_wfm.value[n_word];
1217 tmp_wf[n_word] -= tmp_wf[n_word-2];
1219 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1220 wfm_om->wfm_x[n_position] = (float)
1221 wfm_om->frag_begin_time[n_fragment]
1222 + (frag_count * NSECS_PER_TWR_BIN);
1227 Hack for wrongly merged overlapping fragments
1229 if(tmp_wf[n_word] > 0x1fff)
1232 /* assume that fragment merge in eventbuilder caused */
1233 /* problem two fragments overlap in EXACTLY ONE point */
1234 /* and are merged first point of the added part of */
1235 /* the fragment is encoded using the former fragment */
1236 /* start as a data point */
1238 last_value = tmp_wf[n_word-1];
1239 assumed_frag_begin = 0x4000 + fragment_start + frag_count;
1240 tmp_wf[n_word] = f_wfm.value[n_word] + 2 * last_value;
1241 tmp_wf[n_word] -= assumed_frag_begin;
1242 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1244 /* Look if value is still buggy */
1245 if(tmp_wf[n_word] > 0x1fff) b_wrong_value = 1;
1247 debug = ERROR_MISS_FRAG_STOP;
1249 } /* end year >= 2005 */
1252 /* 2003 2004 data */
1253 wfm_om->wfm_y[n_position] = (float) f_wfm.value[n_word];
1254 wfm_om->wfm_x[n_position] = (float)
1255 wfm_om->frag_begin_time[n_fragment]
1256 + (frag_count * NSECS_PER_TWR_BIN);
1257 } /* end year 2003 2004 */
1259 /* Set min and max Y */
1261 if(wfm_om->wfm_y[n_position] > wfm_om->wfm_max)
1262 wfm_om->wfm_max = wfm_om->wfm_y[n_position];
1263 if(wfm_om->wfm_y[n_position] < wfm_om->wfm_min)
1264 wfm_om->wfm_min = wfm_om->wfm_y[n_position];
1271 if((f_wfm.value[n_word] & 0xf000) == 0x2000) /* Normal wavf */
1274 wfm_om->frag_end[n_fragment] = n_position - 1;
1275 wfm_om->frag_n_points[n_fragment] =
1276 wfm_om->frag_end[n_fragment]
1277 - wfm_om->frag_begin[n_fragment] + 1;
1278 wfm_om->n_point += wfm_om->frag_n_points[n_fragment];
1282 return(ERROR_CORRUPTED_WF);
1285 } /* end while fragment */
1288 wfm_om->n_frag = n_fragment;
1289 if( !(n_word & 0x1) ) n_word++;
1291 if(n_fragment >= MAX_N_OF_FRAGS) return(ERROR_MAX_N_FRAGMENTS_EXCEEDED);
1294 // Hack to get rid of last value of waveform always set to 0
1295 if (wfm_om->wfm_y[wfm_om->n_point] == 0.0)
1297 // erase last point of waveform
1300 // Shorten last pulse if necessary
1301 // if( wfm_om.peak_end[wfm_om.n_peak-1]
1302 // == wfm_om.frag_end[wfm_om.n_frag-1] )
1303 // wfm_om.peak_end[wfm_om.n_peak-1]--;
1305 // Shorten last fragment
1306 wfm_om->frag_n_points[wfm_om->n_frag-1]--;
1307 wfm_om->frag_end[wfm_om->n_frag-1]--;
1309 wfm_om->wfm_min = 4095.0;
1310 wfm_om->wfm_max = 0.0;
1311 for (Int_t i_value=0; i_value < wfm_om->n_point; i_value++)
1313 if (wfm_om->wfm_y[i_value] > wfm_om->wfm_max) wfm_om->wfm_max=wfm_om->wfm_y[i_value];
1314 if (wfm_om->wfm_y[i_value] < wfm_om->wfm_min) wfm_om->wfm_min=wfm_om->wfm_y[i_value];
1320 ///////////////////////////////////////////////////////////////////////////