]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/icepack/iceconvert/IceRawTWR.cxx
28-feb-2007 NvE IceRawTWR.cxx updated to include latest bugfix of Wolfgang in memberf...
[u/mrichter/AliRoot.git] / RALICE / icepack / iceconvert / IceRawTWR.cxx
CommitLineData
0cfe76b5 1/*******************************************************************************
2 * Copyright(c) 2003, IceCube Experiment at the South Pole. All rights reserved.
3 *
4 * Author: The IceCube RALICE-based Offline Project.
5 * Contributors are mentioned in the code where appropriate.
6 *
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 *******************************************************************************/
15
16// $Id$
17
18///////////////////////////////////////////////////////////////////////////
19// Class IceRawTWR
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.
43//
44// Usage example :
45// ---------------
46//
47// gSystem->Load("ralice");
48// gSystem->Load("icepack");
49// gSystem->Load("iceconvert");
50//
51// IceRawTWR q("IceRawTWR","TWR raw data to IcePack data structure conversion");
52//
53// // Limit the number of entries for testing
54// q.SetMaxEvents(10);
55//
56// // Print frequency to produce a short summary print every printfreq events
57// q.SetPrintFreq(1);
58//
59// // The TWR raw data input filename(s)
60// q.AddInputFile("twr_2005_101_009225_0983_57784_57850.dat.twr.to_tape_1");
61//
62// // Output file for the event structures
63// q.SetOutputFile("events.root");
64//
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
70// // as follows :
71// //
72// // MyXtalk task1("task1","Cross talk correction");
73// // MyClean task2("task2","Hit cleaning");
74// // q.Add(&task1);
75// // q.Add(&task2);
76// //
77// // The sub-tasks will be executed in the order as they are entered.
78// ///////////////////////////////////////////////////////////////////
79//
80// // Perform the conversion and execute subtasks (if any)
81// // on an event-by-event basis
82// q.ExecuteJob();
83//
84//--- Author: Nick van Eijndhoven 12-dec-2006 Utrecht University
85//- Modified: NvE $Date$ Utrecht University
86///////////////////////////////////////////////////////////////////////////
87
88#include "IceRawTWR.h"
89#include "Riostream.h"
90
91ClassImp(IceRawTWR) // Class implementation to enable ROOT I/O
92
93IceRawTWR::IceRawTWR(const char* name,const char* title) : AliJob(name,title)
94{
95// Default constructor.
96// By default maxevent=-1, split=0, bsize=32000, printfreq=1.
97
98 fSplit=0;
99 fBsize=32000;
100 fMaxevt=-1;
101 fPrintfreq=1;
102 fInfiles=0;
103 fOutfile=0;
104}
105///////////////////////////////////////////////////////////////////////////
106IceRawTWR::~IceRawTWR()
107{
108// Default destructor.
109
110 if (fInfiles)
111 {
112 delete fInfiles;
113 fInfiles=0;
114 }
115}
116///////////////////////////////////////////////////////////////////////////
117void IceRawTWR::SetMaxEvents(Int_t n)
118{
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.
122 fMaxevt=n;
123}
124///////////////////////////////////////////////////////////////////////////
125void IceRawTWR::SetPrintFreq(Int_t f)
126{
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;
130}
131///////////////////////////////////////////////////////////////////////////
132void IceRawTWR::SetSplitLevel(Int_t split)
133{
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;
137}
138///////////////////////////////////////////////////////////////////////////
139void IceRawTWR::SetBufferSize(Int_t bsize)
140{
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;
144}
145///////////////////////////////////////////////////////////////////////////
146void IceRawTWR::AddInputFile(TString name)
147{
148// Add the name of this TWR raw data input file to the list to be processed.
149
150 if (!fInfiles)
151 {
152 fInfiles=new TObjArray();
153 fInfiles->SetOwner();
154 }
155
156 TObjString* s=new TObjString();
157 s->SetString(name);
158 fInfiles->Add(s);
159}
160///////////////////////////////////////////////////////////////////////////
161void IceRawTWR::SetOutputFile(TFile* ofile)
162{
163// Set the output file for the ROOT data.
164 if (fOutfile) delete fOutfile;
165 fOutfile=ofile;
166}
167///////////////////////////////////////////////////////////////////////////
168void IceRawTWR::SetOutputFile(TString name)
169{
170// Create the output file for the ROOT data.
171 if (fOutfile) delete fOutfile;
6280c0e2 172 fOutfile=new TFile(name.Data(),"RECREATE","TWR raw data in IceEvent structure");
0cfe76b5 173}
174///////////////////////////////////////////////////////////////////////////
175TFile* IceRawTWR::GetOutputFile()
176{
177// Provide pointer to the ROOT output file.
178 return fOutfile;
179}
180///////////////////////////////////////////////////////////////////////////
181void IceRawTWR::Exec(Option_t* opt)
182{
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".
190//
191// Notes :
192// -------
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.
199
200 if (!fInfiles)
201 {
202 cout << " *IceRawTWR Exec* No data input file(s) specified." << endl;
203 return;
204 }
205
206 Int_t ninfiles=fInfiles->GetEntries();
207 if (!ninfiles)
208 {
209 cout << " *IceRawTWR Exec* No data input file(s) specified." << endl;
210 return;
211 }
212
213 TTree* otree=0;
214 if (fOutfile)
215 {
216 otree=new TTree("T","TWR raw data converted to IceEvent structures");
217 otree->SetDirectory(fOutfile);
218 }
219
220 IceEvent* evt=new IceEvent();
221 evt->SetTrackCopy(1);
222 evt->SetDevCopy(1);
223
224 // Branch in the tree for the event structure
225 if (otree) otree->Branch("IceEvent","IceEvent",&evt,fBsize,fSplit);
226
227 // Initialise the job working environment
228 SetMainObject(evt);
229 if (fOutfile)
230 {
231 AddObject(fOutfile);
232 AddObject(otree);
233 }
234
235 TString inputfile;
236
237 cout << " ***" << endl;
238 cout << " *** Start processing of job " << GetName() << " ***" << endl;
239 cout << " ***" << endl;
240 for (Int_t i=0; i<ninfiles; i++)
241 {
242 TObjString* sx=(TObjString*)fInfiles->At(i);
243 if (!sx) continue;
244 inputfile=sx->GetString();
245 cout << " TWR raw data input file : " << inputfile.Data() << endl;
246 }
247 cout << " Maximum number of events to be processed : " << fMaxevt << endl;
248 cout << " Print frequency : " << fPrintfreq << endl;
249 if (fOutfile)
250 {
251 cout << " ROOT output file : " << fOutfile->GetName() << endl;
252 cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
253 }
254
255 ListEnvironment();
256
257 // Storage of the used parameters in the IceRawTWR device
258 AliDevice params;
259 params.SetNameTitle("IceRawTWR","IceRawTWR processor parameters");
260 params.SetSlotName("Nchannels",1);
261 params.SetSlotName("Ntriggers",2);
262 params.SetSlotName("BaselineOffset",3);
263 params.SetSignal(float(N_OF_CHANNELS),1);
264 params.SetSignal(float(N_OF_TRIGGERS),2);
265 params.SetSignal(float(BASELINE_MEAN_MAGIC),3);
266
267 // Set DAQ device info
268 AliDevice daq;
269 daq.SetName("Daq");
270 daq.SetSlotName("TWR",1);
271 daq.SetSignal(1,1);
272
273 twr_raw_data_file_t twr_file;
274 Int_t year,runnum,evtnum;
275
276 Int_t error;
277 UInt_t nhead;
278
279 GPS_t gps;
280 UInt_t gpslow,gpshigh,gpssecs; // The GPS time information
281 Int_t seconds,nsecs; // Seconds and nanoseconds since start of the UT year
282
283 Int_t nevt=0;
284 fHeader=0;
285 for (Int_t ifile=0; ifile<ninfiles; ifile++)
286 {
287 TObjString* sx=(TObjString*)fInfiles->At(ifile);
288 if (!sx) continue;
289
290 inputfile=sx->GetString();
291 if (inputfile=="") continue;
292
293 // Open the TWR raw data input file in binary mode
294 fInput=fopen(inputfile.Data(),"rb");
295
296 if (!fInput)
297 {
298 cout << " *IceRawTWR Exec* No input file found with name : " << inputfile.Data() << endl;
299 continue;
300 }
301
302 // Extract info like run number, file number etc... from filename
303 extract_info_from_filename((char*)inputfile.Data(),&twr_file);
304
305 year=twr_file.year;
306 runnum=twr_file.run_no;
307
308 // Initialise the event structure
309 clear_event(&fEvent);
310
311 // Read the file header information
312 error=read_header_from_file(fInput,&fHeader,&nhead);
313
314 if (error || !nhead)
315 {
316 cout << " *IceRawTWR Exec* Error in header for input file : " << inputfile.Data() << endl;
317 continue;
318 }
319
320 // Correct the mapping
321 update_system(fHeader,runnum);
322
323 while (!read_event(fInput,fHeader,&fEvent))
324 {
325 if (fMaxevt>-1 && nevt>=fMaxevt) break;
326
327 evtnum=fEvent.eventcounter;
328
329 // The GPS telegram info
330 gps=fEvent.gps;
6280c0e2 331 gpslow=gps.seconds & 0x00FFFFFF; // The low 24 bits of the seconds count
332 gpshigh=gps.info.bits.seconds; // The high 8 bits of the seconds count
0cfe76b5 333 gpssecs=gpshigh<<24;
334 gpssecs+=gpslow;
335
336 // Seconds and nanoseconds since the start of the UT year
337 seconds=gpssecs;
338 nsecs=100*gps.count_10MHz;
45bba4c4 339
340 // Correction for GPS telegram interpretation in the TWR Daq
341 if (year<2007) seconds-=24*3600;
0cfe76b5 342
343 // Reset the complete Event structure
344 evt->Reset();
345
346 evt->SetRunNumber(runnum);
347 evt->SetEventNumber(evtnum);
348 evt->SetUT(year,0,seconds,nsecs);
349
350 evt->AddDevice(params);
351 evt->AddDevice(daq);
352
353 PutTrigger(year);
354
355 PutWaveforms(year);
356
357 // Invoke all available sub-tasks (if any)
358 CleanTasks();
359 ExecuteTasks(opt);
360
361 if (fPrintfreq)
362 {
363 if (!(nevt%fPrintfreq)) evt->HeaderData();
364 }
365
366 // Write the complete structure to the output Tree
367 if (otree) otree->Fill();
368
369 // Update event counter
370 nevt++;
371
372 // Reset the raw event structure
373 clear_event(&fEvent);
374 } // End of event reading loop
375
376 // Delete the file header structure
377 clear_system(fHeader);
378
379 if (fMaxevt>-1 && nevt>=fMaxevt) break;
380
381 } // End of input file loop
382
383 // Flush possible memory resident data to the output file
384 if (fOutfile) fOutfile->Write();
385
386 // Remove the IceEvent object from the environment
387 // and delete it as well
388 if (evt)
389 {
390 RemoveObject(evt);
391 delete evt;
392 }
393}
394///////////////////////////////////////////////////////////////////////////
395void IceRawTWR::PutWaveforms(Int_t year)
396{
397// Get the waveform info from the raw data event into the IcePack structure.
398
399 IceEvent* evt=(IceEvent*)GetMainObject();
400 if (!evt) return;
401
402 // Loop over all the waveforms and add the histo(s) to the corresponding OM's
403 TH1F histo;
404 Int_t nbins=0;
405 Float_t xlow=0;
406 Float_t xup=0;
407 TString hname;
408 IceAOM om;
409 IceAOM* omx=0;
410 Int_t omid;
1f252619 411 Int_t omidmax=677;
0cfe76b5 412 Int_t error;
413 Float_t baseline;
eb416c1b 414 Int_t nfrags;
415 Int_t firstbin,lastbin;
0cfe76b5 416 for (Int_t i=0; i<N_OF_CHANNELS; i++)
417 {
418 if (!fEvent.wfm_filled[i]) continue;
419
1f252619 420 omid=i;
0cfe76b5 421 if (omid<=0 || omid>omidmax) continue; // Skip trigger channels
422
423 // Get corresponding device from the current event structure
424 omx=(IceAOM*)evt->GetIdDevice(omid);
425 if (!omx)
426 {
427 om.Reset(1);
428 om.SetUniqueID(omid);
429 evt->AddDevice(om);
430 omx=(IceAOM*)evt->GetIdDevice(omid);
431 }
432
433 if (!omx) continue;
434
435 clear_waveform_analysis(&fWform);
436 error=restore_waveform(fEvent.wfm[i],&fWform,year);
437
438 if (error) continue;
439
eb416c1b 440 nfrags=fWform.n_frag;
0cfe76b5 441
eb416c1b 442 for (Int_t ifrag=0; ifrag<nfrags; ifrag++)
443 {
444 baseline=fWform.frag_mean[ifrag];
0cfe76b5 445
eb416c1b 446 hname="BASELINE-WF";
447 hname+=omx->GetNwaveforms()+1;
448 omx->AddNamedSlot(hname);
449 omx->SetSignal(baseline,hname);
0cfe76b5 450
eb416c1b 451 // Fill the waveform histogram with this fragment
452 hname="OM";
453 hname+=omid;
454 hname+="-WF";
455 hname+=omx->GetNwaveforms()+1;
0cfe76b5 456
eb416c1b 457 histo.Reset();
458 histo.SetName(hname.Data());
459 nbins=fWform.frag_n_points[ifrag];
460 firstbin=fWform.frag_begin[ifrag];
461 lastbin=fWform.frag_end[ifrag];
0cfe76b5 462
eb416c1b 463 xlow=fWform.wfm_x[firstbin];
464 xup=fWform.wfm_x[lastbin];
465
466 histo.SetBins(nbins,xlow,xup);
467
468 for (Int_t jbin=1; jbin<=nbins; jbin++)
469 {
470 histo.SetBinContent(jbin,baseline-fWform.wfm_y[firstbin+jbin-1]);
471 }
472
473 omx->SetWaveform(&histo,omx->GetNwaveforms()+1);
474 } // End of loop over fragments of this OM
475 } // End of loop over channels
0cfe76b5 476}
477///////////////////////////////////////////////////////////////////////////
478void IceRawTWR::PutTrigger(Int_t year)
479{
480// Get the trigger info from the raw data event into the IcePack structure.
481// Currently only the trigger settings for the years 2005 and 2006 have been
482// implemented.
483// In addition to the hardware and software triggers as encountered in the
484// raw data, an artificial "main" trigger has been introduced.
485// This artificial "main" trigger is just an "or" of the standard hard and soft
486// triggers (except calibration and random triggers) and serves only to
487// provide a generic "main" trigger a la Amanda mu-daq so that the default
488// "IceCleanHits" hit cleaning procedure will work correctly.
489// The trigger time for the artificial "main" trigger is taken to be the
490// time of the earliest hardware trigger pulse. In case there is no hardware
491// trigger pulse available, the "main" trigger time is set to 0.
492// For other years, only the artificial "main" trigger with a trigger time
493// set to 0 will be stored in the IceEvent structure.
494
495 // Fill the trigger structure
496 Int_t error=retrigger(&fEvent,&fTrigger);
497 if (error) return;
498
499 IceEvent* evt=(IceEvent*)GetMainObject();
500 if (!evt) return;
501
502 AliDevice trig;
503 trig.SetNameTitle("Trigger","Amanda/IceCube event triggers");
504 AliSignal s;
505 Float_t trigtime=0;
506
507 if (year !=2005 && year != 2006)
508 {
509 s.SetName("main");
510 s.SetUniqueID(0);
511 s.SetSlotName("trig_pulse_le",1);
512 s.SetSignal(trigtime,1);
513 trig.AddHit(s);
514 // Store the trigger data into the IceEvent structure
515 evt->AddDevice(trig);
516 return;
517 }
518
519 // Trigger settings for 2005 and 2006
520 if (!fTrigger.n_software_trigger && !fTrigger.n_hardware_trigger) return;
521
522 TString trignames[N_OF_TRIGGERS]={"m24","m18","string","spase","cal-t0","cal-la","m12",
523 "main-logic","main-or","random","m20-frag","volume"};
524 Int_t imain=0;
525 for (Int_t i=0; i<N_OF_TRIGGERS; i++)
526 {
527 if (!fTrigger.trigger_active[i]) continue;
528
529 s.Reset(1);
530 s.SetName(trignames[i]);
531 s.SetUniqueID(i);
532 trigtime=0;
533 if (fTrigger.trigger_has_pulse[i]) trigtime=fTrigger.trigger_time[i];
534 s.SetSlotName("trig_pulse_le",1);
535 s.SetSignal(trigtime,1);
536 trig.AddHit(s);
537 // Set flag to indicate creation of artificial "main" trigger
538 if (i!=4 && i!=5 && i!=9) imain=1;
539 }
540
541 // Set the artificial "main" trigger
542 if (imain)
543 {
544 s.Reset(1);
545 s.SetName("main");
546 s.SetUniqueID(N_OF_TRIGGERS);
547 s.SetSlotName("trig_pulse_le",1);
548 trigtime=0;
549 if (fTrigger.first_trigger>=0) trigtime=fTrigger.first_trigger_time;
550 s.SetSignal(trigtime,1);
551 trig.AddHit(s);
552 }
553
554 // Store the trigger data into the IceEvent structure
555 evt->AddDevice(trig);
556}
557///////////////////////////////////////////////////////////////////////////
558Int_t IceRawTWR::extract_info_from_filename(char* fname,twr_raw_data_file_t* twr_file)
559{
560 char start_str[20],year_str[20],day_str[20],run_no_str[20],
561 file_no_str[20],begin_str[20],end_str[20];
562 char* filename;
563
564 filename = strstr(fname, "twr");
565 if(filename == NULL)
566 if(strncmp("twr_", start_str, 4))
567 {
568 printf("%s\n", filename);
569 return(ERROR_NOT_VALID_FILENAME);
570 }
571
572 strncpy(start_str, filename, 4);
573 if(strncmp("twr_", start_str, 4))
574 {
575 printf("%s %s\n", filename, start_str);
576 return(ERROR_NOT_VALID_FILENAME);
577 }
578 strncpy(year_str, &filename[4], 4);
579 twr_file->year = strtol(year_str, 0, 10);
580
581 if(twr_file->year==2003)
582 {
583 strncpy(day_str, &filename[9], 3);
584 day_str[3] = '\0';
585 twr_file->day = strtol(day_str, 0, 10);
586
587 strncpy(run_no_str, &filename[13], 4);
588 run_no_str[4] = '\0';
589 twr_file->run_no = strtol(run_no_str, 0, 10);
590
591 strncpy(file_no_str, &filename[18], 4);
592 file_no_str[4] = '\0';
593 twr_file->file_no = strtol(file_no_str, 0, 10);
594 }
595
596 if(twr_file->year==2004)
597 {
598 strncpy(day_str, &filename[9], 3);
599 day_str[3] = '\0';
600 twr_file->day = strtol(day_str, 0, 10);
601
602 strncpy(run_no_str, &filename[13], 4);
603 run_no_str[4] = '\0';
604 twr_file->run_no = strtol(run_no_str, 0, 10);
605
606 strncpy(file_no_str, &filename[18], 4);
607 file_no_str[4] = '\0';
608 twr_file->file_no = strtol(file_no_str, 0, 10);
609
610 strncpy(begin_str, &filename[23], 5);
611 begin_str[5] = '\0';
612 twr_file->begin = strtol(begin_str, 0, 10);
613
614 strncpy(end_str, &filename[29], 5);
615 end_str[5] = '\0';
616 twr_file->end = strtol(end_str, 0, 10);
617 }
618
619 if(twr_file->year > 2004)
620 {
621 strncpy(day_str, &filename[9], 3);
622 day_str[3] = '\0';
623 twr_file->day = strtol(day_str, 0, 10);
624
625 strncpy(run_no_str, &filename[13], 6);
626 run_no_str[6] = '\0';
627 twr_file->run_no = strtol(run_no_str, 0, 10);
628
629 strncpy(file_no_str, &filename[20], 4);
630 file_no_str[4] = '\0';
631 twr_file->file_no = strtol(file_no_str, 0, 10);
632
633 strncpy(begin_str, &filename[25], 5);
634 begin_str[5] = '\0';
635 twr_file->begin = strtol(begin_str, 0, 10);
636
637 strncpy(end_str, &filename[31], 5);
638 end_str[5] = '\0';
639 twr_file->end = strtol(end_str, 0, 10);
640 }
641 return(0);
642}
643///////////////////////////////////////////////////////////////////////////
644Int_t IceRawTWR::clear_system(sys_config_t* sys)
645{
646// Deletion of the file header structure.
647
648 if (!sys) return 0;
649
f9556244 650 for(Int_t icrate=0; icrate < int(sys->n_crates); icrate++)
0cfe76b5 651 {
652 if (!sys->crate[icrate]) continue;
f9556244 653 for(Int_t itwr=0; itwr < int(sys->crate[icrate]->n_twr); itwr++)
0cfe76b5 654 {
655 if (sys->crate[icrate]->twr[itwr]) delete sys->crate[icrate]->twr[itwr];
656 }
657 delete sys->crate[icrate];
658 }
659 delete sys;
660 sys=0;
661 return 0;
662}
663///////////////////////////////////////////////////////////////////////////
664Int_t IceRawTWR::clear_event(event_t* event_ptr)
665{
666 Int_t i_value;
667 Int_t *int_ptr = (int*) event_ptr;
668
f9556244 669 for(i_value=0; i_value < int(sizeof(event_t)/sizeof(Int_t)); i_value++)
0cfe76b5 670 {
671 *int_ptr++ = 0;
672 }
673 return(0);
674}
675///////////////////////////////////////////////////////////////////////////
676Int_t IceRawTWR::read_header_from_file(FILE* fin,sys_config_t** system_ptr,UInt_t* header_length)
677{
678 Int_t i_crate, i_twr, i_channel;
679 UInt_t count_twr_in_system = 0;
0cfe76b5 680 UInt_t dummy;
681
682 sys_config_t *sys;
683
684 // allocating memory for sys_config structure
685 sys = (sys_config_t*) malloc( sizeof(sys_config_t) );
686
687 fread(&dummy,sizeof(UInt_t),1,fin); // Header Begin Mark
688
689 fread(header_length,sizeof(UInt_t),1,fin); // Length of header
690 fread(&sys->clockdiv,sizeof(UInt_t),1,fin);
691 fread(&sys->n_crates,sizeof(UInt_t),1,fin);
692
693 if( (sys->n_crates > MAX_N_CRATES) || (sys->n_crates < 0) )
694 return(ERROR_TOO_MANY_CRATES);
695
f9556244 696 for(i_crate=0; i_crate < int(sys->n_crates); i_crate++)
0cfe76b5 697 {
698 sys->crate[i_crate] =
699 (crate_config_t*) malloc( sizeof(crate_config_t) );
700
701 fread(&sys->crate[i_crate]->vme_base_bridge,sizeof(UInt_t),1,fin);
702 fread(&sys->crate[i_crate]->vme_base_100MHz,sizeof(UInt_t),1,fin);
703 fread(&sys->crate[i_crate]->base_gps,sizeof(UInt_t),1,fin);
704 fread(&sys->crate[i_crate]->n_twr,sizeof(UInt_t),1,fin);
705
706 if( (sys->crate[i_crate]->n_twr > MAX_N_TWR_PER_CRATE)
707 || (sys->crate[i_crate]->n_twr < 0) )
708 return(ERROR_TOO_MANY_TWRS);
709
f9556244 710 for(i_twr=0; i_twr < int(sys->crate[i_crate]->n_twr); i_twr++)
0cfe76b5 711 {
712 sys->crate[i_crate]->twr[i_twr] =
713 (twr_config_t*) malloc( sizeof(twr_config_t) );
714 count_twr_in_system++;
715 fread(&sys->crate[i_crate]->twr[i_twr]->base,
716 sizeof(UInt_t),1,fin);
717 fread(&sys->crate[i_crate]->twr[i_twr]->id,
718 sizeof(UInt_t),1,fin);
719
720 sys->crate[i_crate]->twr[i_twr]->id
721 = sys->crate[i_crate]->twr[i_twr]->id - 0x10; /* Correct */
722
723
724 fread(&dummy,sizeof(UInt_t),1,fin); /* stat_reg */
725 fread(&sys->crate[i_crate]->twr[i_twr]->mod_id,
726 sizeof(UInt_t),1,fin);
727 fread(&dummy,sizeof(UInt_t),1,fin); /* acq_ctrl */
728 fread(&sys->crate[i_crate]->twr[i_twr]->ext_start,
729 sizeof(UInt_t),1,fin);
730 fread(&sys->crate[i_crate]->twr[i_twr]->ext_stop,
731 sizeof(UInt_t),1,fin);
732 fread(&dummy,sizeof(UInt_t),1,fin); /* evtconfig */
733
734 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
735 {
736 fread(&sys->crate[i_crate]->twr[i_twr]->om_no[i_channel],
737 sizeof(UInt_t),1,fin);
738 }
739
740 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
741 {
742 fread(&sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel],
743 sizeof(UInt_t),1,fin);
744 }
745
746 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
747 {
748 fread(&sys->crate[i_crate]->twr[i_twr]->baseline[i_channel],
749 sizeof(UInt_t),1,fin);
750 }
751
752 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
753 {
754 fread(&sys->crate[i_crate]->twr[i_twr]->threshold[i_channel],
755 sizeof(UInt_t),1,fin);
756 }
757
758 sys->twr_field[(i_crate * 0x10) + i_twr]
759 = sys->crate[i_crate]->twr[i_twr];
760
761 /* Bug fix needed */
762 for(i_channel=0; i_channel < 8; i_channel++)
763 {
764 if( sys->crate[i_crate]->twr[i_twr]->om_no[i_channel] == 9000 )
765 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]
766 = N_OF_CHANNELS - 1;
767 }
768 }
769 }
770
771 // Set number of TWRs in system
772 sys->n_twr = count_twr_in_system;
773
774 *system_ptr = sys;
775 return(0);
776}
777///////////////////////////////////////////////////////////////////////////
778Int_t IceRawTWR::update_system(sys_config_t* sys,Int_t run_number)
779{
780 Int_t i_crate, i_twr, i_channel;
781
eb416c1b 782 // Data for bug fix 1 by Andreas
0cfe76b5 783 UInt_t om_no_r1[CHANNELS_PER_TWR]
784 = {111, 112, 113, 114, 115, 116, 39, 118};
785 UInt_t om_is_optical_r1[CHANNELS_PER_TWR]
786 = {0, 0, 0, 0, 0, 0, 0, 0};
787 UInt_t threshold_r1[CHANNELS_PER_TWR]
788 = {50, 50, 50, 50, 50, 50, 80, 50};
789
eb416c1b 790 // Data for bugfix 2 by Timo
0cfe76b5 791 UInt_t om_no_r2[CHANNELS_PER_TWR]
792 = {473, 484, 485, 486, 487, 475, 490, 491};
793 UInt_t om_is_optical_r2[CHANNELS_PER_TWR]
794 = {1, 1, 1, 1, 1, 1, 1, 1};
795 UInt_t threshold_r2[CHANNELS_PER_TWR]
796 = {15, 50, 55, 40, 15, 23, 15, 15};
797
eb416c1b 798 // Data for bugfix 3 by Wolfgang
799 // Old (=incorrect) OM config : {183, 184, 185, 38, 187, 188, 189, 190}
800 UInt_t om_no_r3[CHANNELS_PER_TWR]={345, 184, 185, 38, 187, 188, 189, 190};
801 UInt_t om_is_optical_r3[CHANNELS_PER_TWR]={1, 0, 0, 0, 0, 0, 0, 0};
802 UInt_t threshold_r3[CHANNELS_PER_TWR]={20, 50, 50, 80, 50, 50, 50, 50};
803
804 // Old (=incorrect) OM config : {345, 346, 454, 450, 635, 10000, 10000, 10000}
805 UInt_t om_no_r4[CHANNELS_PER_TWR]={183, 346, 454, 450, 635, 10000, 10000, 10000};
806 UInt_t om_is_optical_r4[CHANNELS_PER_TWR]={0, 1, 1, 1, 1, 1, 1, 1};
807 UInt_t threshold_r4[CHANNELS_PER_TWR]={50, 20, 20, 20, 20, 500, 500, 500};
0cfe76b5 808
eb416c1b 809 // Bugfix 1 Andreas Bug
810
811 // By accident this TWR was counted twice in TWR.cnf
812 // as Crate 0 TWR 7 and Crate 4 TWR 7
813 // from run 9153 up to run 9841 (incl.)
814 // TWR_OM 639 642 1 9 10 11 12 30
815 // OPTICAL 0 0 0 0 0 0 0 0
816 // TWR_BASELINE 110 120 110 140 150 160 170 180
817 // TWR_THRESHOLD 50 50 80 80 80 80 80 80
818
819 // Crate 4 TWR 7 should be replaced with this TWR
820 // TWR_OM 111 112 113 114 115 116 39 118
821 // OPTICAL 0 0 0 0 0 0 0 0
822 // TWR_BASELINE 110 120 130 140 150 160 170 180
823 // TWR_THRESHOLD 50 50 50 50 50 50 80 50
824
825 // Begin season 2005 13-feb-2005
826 // Timo corrected TWR.cnf on 05-apr-2006 after run 9841
827 if (run_number>=9153 && run_number<=9841)
828 {
829 i_crate = 4;
830 i_twr = 7;
831 for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
832 {
833 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r1[i_channel];
834 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r1[i_channel];
835 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r1[i_channel];
836 }
837 }
838
839 // Bugfix 2 Timos Bug
840
841 // By accident this TWR was counted twice in TWR.cnf
842 // as Crate 0 TWR 1 and Crate 5 TWR b
843 // from run 9153 up to run 9188 (incl.)
844
845 // TWR_OM 492 493 495 496 497 499 500 501
846 // OPTICAL 1 1 1 1 1 1 1 1
847 // TWR_BASELINE 110 120 130 140 150 160 170 180
848 // TWR_THRESHOLD 16 45 25 42 35 46 15 15
849
850 // Crate 5 TWR b should be corrected to
851 // TWR_OM 473 484 485 486 487 475 490 491
852 // OPTICAL 1 1 1 1 1 1 1 1
853 // TWR_BASELINE 4000 120 130 140 150 4000 170 180
854 // TWR_THRESHOLD 15 50 55 40 15 23 15 15
855
856 // Begin season 2005 : 13-feb-2005
857 // Timo corrected TWR.cnf on 15-mar-2005 (= day 74) after run 9188
858 if (run_number>=9153 && run_number<=9188)
859 {
860 i_crate = 5;
861 i_twr = 0xb;
862 for(i_channel=0; i_channel<CHANNELS_PER_TWR; i_channel++)
863 {
864 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r2[i_channel];
865 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r2[i_channel];
866 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r2[i_channel];
867 }
868 }
869
870 // Bugfix 3 by Wolfgang Wagner : Mismatch of OM 345 and 183
871 // Begin season 2005 : 13-feb-2005
872 // Wolfgang corrected TWR.cnf on 15-aug-2005 after run 9988
873 if (run_number>=9153 && run_number<=9988)
874 {
875 i_crate=5;
876 i_twr=4;
877 for(i_channel=0; i_channel<CHANNELS_PER_TWR; i_channel++)
878 {
879 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r3[i_channel];
880 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r3[i_channel];
881 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r3[i_channel];
882 }
883
884 i_twr=5;
885 for(i_channel=0; i_channel<CHANNELS_PER_TWR; i_channel++)
886 {
887 sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]=om_no_r4[i_channel];
888 sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel]=om_is_optical_r4[i_channel];
889 sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]=threshold_r4[i_channel];
890 }
891 }
0cfe76b5 892
0cfe76b5 893 return(0);
894}
895///////////////////////////////////////////////////////////////////////////
896Int_t IceRawTWR::read_event(FILE* fin,sys_config_t* sys,event_t* event_ptr)
897{
f9556244 898 Int_t i_wfm;
899 UInt_t length_of_event_block;
0cfe76b5 900
901 Int_t n_twr, n_of_waveforms_in_event, read_number;
902 UInt_t length_wfm[CHANNELS_PER_TWR];
903 UInt_t dummy, channel_no, om_no, twr_no;
904
905 // Reset waveform filled register
906 memset(&event_ptr->wfm_filled[0], 0, sizeof(UInt_t) * N_OF_CHANNELS);
907
908 if( !fread(&dummy,sizeof(UInt_t),1,fin) ) return(1);
909
910 if(dummy != 0xbbbbbbbb)
911 {
912 printf("Wrong event begin mark %x\n", dummy);
913 while( (dummy !=0xbbbbbbbb)
914 && (fread(&dummy,sizeof(UInt_t),1,fin) != 0) )
915 {;//printf("dummy:%x\n", dummy);
916 }
917 }
918 if( !fread(&length_of_event_block,sizeof(UInt_t),1,fin) ) return(1);
919 if( !fread(&event_ptr->eventcounter,sizeof(UInt_t),1,fin) ) return(1);
920 if( !fread(&event_ptr->which_trigger,sizeof(UInt_t),1,fin) ) return(1);
921 if( !fread(&event_ptr->gps,sizeof(GPS_t),1,fin) ) return(1);
922
923 // --reading waveforms from TWR blocks
924 n_twr = 0;
f9556244 925 while(n_twr < int(sys->n_twr))
0cfe76b5 926 {
927 // --read TWR header
928 if( !fread(&dummy,sizeof(UInt_t),1,fin) ) return(1);
929 if(dummy != 0xffffffff)
930 {printf("Wrong twr begin mark %x\n", dummy); return(2);}
931 if( !fread(&twr_no,sizeof(UInt_t),1,fin) ) return(1);
932
933 // nur voruebergehend !!
934 twr_no -= 0x10;
935
936 if( !fread(&event_ptr->twr[twr_no].timestamp,sizeof(UInt_t),1,fin) )
937 return(1);
938 if( !fread(&n_of_waveforms_in_event,sizeof(UInt_t),1,fin) )
939 return(1);
940 event_ptr->twr[twr_no].n_wfm = n_of_waveforms_in_event;
941
942 for(i_wfm=0; i_wfm < n_of_waveforms_in_event; i_wfm++)
943 {
944 if( !fread(&length_wfm[i_wfm],sizeof(UInt_t),1,fin) ) return(1);
945 }
946
947 // read waveforms
948 for(i_wfm=0; i_wfm < n_of_waveforms_in_event; i_wfm++)
949 {
950 if(length_wfm[i_wfm] != 0)
951 {
952 if( !fread(&channel_no,sizeof(UInt_t),1,fin) ) return(1);
953 if(sys->twr_field[twr_no]->om_no[channel_no]
954 < N_OF_CHANNELS)
955 om_no = sys->twr_field[twr_no]->om_no[channel_no];
956 else
957 om_no = N_OF_CHANNELS-1;
958
959 /* Fix needed */
960
961 event_ptr->twr_id_of_om[om_no] = twr_no;
962
963 read_number = fread(&event_ptr->wfm[om_no],
964 length_wfm[i_wfm]-sizeof(UInt_t),1,fin);
965 event_ptr->wfm_filled[om_no] = 1;
966 if( !read_number ) return(1);
967
968 // read_number correction for usage of fread() instead of read()
969 read_number*=length_wfm[i_wfm]-sizeof(UInt_t);
970
f9556244 971 if( read_number != int(length_wfm[i_wfm]-sizeof(UInt_t)) )
0cfe76b5 972 {
973 cout << " read_number : " << read_number
974 << " length_wfm["<<i_wfm<<"] : " << length_wfm[i_wfm]
975 << " sizeof(UInt_t) : " << sizeof(UInt_t) << endl;
976 return(2);
977 }
978 }
979 }
980 n_twr++;
981 } // end while n_twr
982 return(0);
983}
984///////////////////////////////////////////////////////////////////////////
985Int_t IceRawTWR::retrigger(event_t* ev,trigger_hits_t* trig)
986{
987// Returns the active trigger(s)
988
989 // Initialise the trigger_hits_t structure with zeroes
990 memset(trig, 0, sizeof(trigger_hits_t) );
991
992 // Obtain the software trigger info
993 trig->n_software_trigger=0;
994 for(Int_t itrigger=0; itrigger<N_OF_TRIGGERS; itrigger++)
995 {
996 if(ev->which_trigger & trigger_bits[itrigger])
997 {
998 //printf("SetTrigger %i\n", i_trigger);
999 trig->trigger_active[itrigger]=1;
1000 trig->n_software_trigger++;
1001 }
1002 else
1003 {
1004 trig->trigger_active[itrigger]=0;
1005 }
1006 }
1007
1008 // Obtain the hardware trigger info
1009 trig->n_hardware_trigger=0;
1010 trig->first_trigger_time=10000000;
1011 trig->first_trigger=-1;
1012
1013 for(Int_t jtrigger=0; jtrigger<N_OF_TRIGGERS; jtrigger++)
1014 {
1015 if(!trigger_channel[jtrigger]) continue;
1016
1017 if(ev->wfm_filled[trigger_channel[jtrigger]])
1018 {
1019 trig->trigger_active[jtrigger]=1;
1020 trig->trigger_time[jtrigger]=(ev->wfm[trigger_channel[jtrigger]].value[2] & 0xfff);
1021 trig->trigger_has_pulse[jtrigger]=1;
1022 if (trig->trigger_time[jtrigger] < trig->first_trigger_time)
1023 {
1024 trig->first_trigger_time=trig->trigger_time[jtrigger];
1025 trig->first_trigger=jtrigger;
1026 }
1027 trig->n_hardware_trigger++;
1028 }
1029 }
1030 return 0;
1031}
1032///////////////////////////////////////////////////////////////////////////
1033Int_t IceRawTWR::clear_waveform_analysis(waveform_analyse_t* wfm_om)
1034{
1035 Int_t i_value, i_frag, i_edge, i_peak;
1036
1037 if(wfm_om == 0) return(1);
1038
1039 // output from analysis
1040 wfm_om->n_frag = 0;
1041 for(i_frag=0; i_frag < MAX_N_OF_FRAGS; i_frag++)
1042 {
1043 wfm_om->frag_n_points[i_frag] = 0;
1044 wfm_om->frag_begin[i_frag] = 0;
1045 wfm_om->frag_end[i_frag] = 0;
1046 wfm_om->frag_mean[i_frag] = 0;
1047 wfm_om->frag_begin_time[i_frag] = 0;
1048 }
1049
1050 wfm_om->n_peak = 0;
1051 for(i_peak=0; i_peak < MAX_N_OF_PEAKS; i_peak++)
1052 {
1053 wfm_om->peak_begin[i_peak] = 0;
1054 wfm_om->peak_end[i_peak] = 0;
1055 wfm_om->peak_max[i_peak] = 0;
1056 wfm_om->peak_TDC_edge[i_peak] = 0;
1057 wfm_om->peak_local_minimum[i_peak] = 0;
1058 wfm_om->crosstalk_charge_n_value[i_peak] = 0;
1059 wfm_om->peak_in_fragment[i_peak] = 0;
1060
1061 wfm_om->peak_mean[i_peak] = 0.0;
1062
1063 wfm_om->peak_m[i_peak] = 0.0;
1064 wfm_om->peak_b[i_peak] = 0.0;
1065 wfm_om->peak_t0[i_peak] = 0.0;
1066 wfm_om->peak_begin_time[i_peak] = 0.0;
1067 wfm_om->peak_charge[i_peak] = 0.0;
1068 wfm_om->peak_height[i_peak] = 0.0;
1069 wfm_om->fitted_amplitude[i_peak] = 0.0;
1070 wfm_om->fitted_TOT[i_peak] = 0.0;
1071 wfm_om->crosstalk_charge[i_peak] = 0.0;
1072 wfm_om->crosstalk_slope[i_peak] = 0.0;
1073 }
1074
1075 wfm_om->n_point = 0;
1076 wfm_om->wfm_min = 4095;
1077 wfm_om->wfm_max = 0;
1078 wfm_om->b_out_of_range = 0;
1079
1080 for(i_value=0; i_value < 1024; i_value++)
1081 {
1082 wfm_om->wfm_x[i_value] = 0;
1083 wfm_om->wfm_y[i_value] = 0;
1084 }
1085
1086 wfm_om->n_tdc_edges = 0;
1087 for(i_edge=0; i_edge < MAX_N_OF_TDC_EDGES; i_edge++)
1088 {
1089 wfm_om->leading_edge[i_edge] = 0.0;
1090 wfm_om->falling_edge[i_edge] = 0.0;
1091 wfm_om->identified_twr_hit[i_edge] = -1;
1092 }
1093
1094 return(0);
1095}
1096///////////////////////////////////////////////////////////////////////////
1097Int_t IceRawTWR::restore_waveform(waveform_t f_wfm,waveform_analyse_t* wfm_om,Int_t year)
1098{
1099 UShort_t wfm_length, mean;
1100 static UShort_t tmp_wf[2000];
1101
1102 Int_t debug = 0;
1103 Int_t fragment_start = 0;
1104 Int_t frag_count = 0; // position in current fragment
1105 Int_t n_position = 0; // position in displayed waveform
1106 UInt_t n_word = 2; // position in featured waveform
1107 Int_t n_fragment = 0; // actual fragment
1108 Int_t b_wrong_value = 0;
1109
1110 UShort_t assumed_frag_begin, last_value; /* bug in eventbuilder */
1111
1112 wfm_om->wfm_min = 4095.0;
1113 wfm_om->wfm_max = 0.0;
1114
1115 if( (f_wfm.value[0] & 0xf000) != 0xf000 ) return(1);
1116 wfm_length = (f_wfm.value[0] & 0xfff)/2;
1117
1118 mean = f_wfm.value[1] + BASELINE_MEAN_MAGIC;
1119 while( ((f_wfm.value[n_word] & 0xf000) == 0x4000) &&
1120 (n_word < wfm_length) &&
1121 (n_fragment < MAX_N_OF_FRAGS) )
1122 {
1123 fragment_start = f_wfm.value[n_word] & 0xfff;
1124 n_word++;
1125 wfm_om->frag_begin_time[n_fragment]
1126 = fragment_start * NSECS_PER_TWR_BIN;
1127 wfm_om->frag_begin[n_fragment] = n_position;
1128 wfm_om->frag_mean[n_fragment] = mean;
1129
1130 b_wrong_value = 0;
1131 frag_count = 0;
1132
1133 while( ((f_wfm.value[n_word] & 0xf000) != 0x2000) &&
1134 ((f_wfm.value[n_word] & 0xf000) != 0x4000) &&/*Reconstructable*/
1135 !b_wrong_value && /* Buggy */
1136 (n_word < wfm_length) )
1137 {
1138 if(year > 2004)
1139 {
1140 /* 2005 2006 data */
1141 if(frag_count == 0)
1142 {
1143 tmp_wf[n_word] = f_wfm.value[n_word] + mean;
1144 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1145 wfm_om->wfm_x[n_position] = (float)
1146 wfm_om->frag_begin_time[n_fragment]
1147 + (frag_count * NSECS_PER_TWR_BIN);
1148 }
1149 else if(frag_count == 1)
1150 {
1151 tmp_wf[n_word] = f_wfm.value[n_word] + tmp_wf[n_word-1];
1152 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1153 wfm_om->wfm_x[n_position] = (float)
1154 wfm_om->frag_begin_time[n_fragment]
1155 + (frag_count * NSECS_PER_TWR_BIN);
1156 }
1157 else
1158 {
1159 tmp_wf[n_word] =
1160 2*tmp_wf[n_word-1] + f_wfm.value[n_word];
1161 tmp_wf[n_word] -= tmp_wf[n_word-2];
1162
1163 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1164 wfm_om->wfm_x[n_position] = (float)
1165 wfm_om->frag_begin_time[n_fragment]
1166 + (frag_count * NSECS_PER_TWR_BIN);
1167 }
1168
1169
1170 /*
1171 Hack for wrongly merged overlapping fragments
1172 */
1173 if(tmp_wf[n_word] > 0x1fff)
1174 {
1175 /* BUG FIXXXX */
1176 /* assume that fragment merge in eventbuilder caused */
1177 /* problem two fragments overlap in EXACTLY ONE point */
1178 /* and are merged first point of the added part of */
1179 /* the fragment is encoded using the former fragment */
1180 /* start as a data point */
1181
1182 last_value = tmp_wf[n_word-1];
1183 assumed_frag_begin = 0x4000 + fragment_start + frag_count;
1184 tmp_wf[n_word] = f_wfm.value[n_word] + 2 * last_value;
1185 tmp_wf[n_word] -= assumed_frag_begin;
1186 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
1187
1188 /* Look if value is still buggy */
1189 if(tmp_wf[n_word] > 0x1fff) b_wrong_value = 1;
1190
1191 debug = ERROR_MISS_FRAG_STOP;
1192 }
1193 } /* end year >= 2005 */
1194 else
1195 {
1196 /* 2003 2004 data */
1197 wfm_om->wfm_y[n_position] = (float) f_wfm.value[n_word];
1198 wfm_om->wfm_x[n_position] = (float)
1199 wfm_om->frag_begin_time[n_fragment]
1200 + (frag_count * NSECS_PER_TWR_BIN);
1201 } /* end year 2003 2004 */
1202
1203 /* Set min and max Y */
1204
1205 if(wfm_om->wfm_y[n_position] > wfm_om->wfm_max)
1206 wfm_om->wfm_max = wfm_om->wfm_y[n_position];
1207 if(wfm_om->wfm_y[n_position] < wfm_om->wfm_min)
1208 wfm_om->wfm_min = wfm_om->wfm_y[n_position];
1209
1210 n_position++;
1211 n_word++;
1212 frag_count++;
1213 }
1214
1215 if((f_wfm.value[n_word] & 0xf000) == 0x2000) /* Normal wavf */
1216 {
1217
1218 wfm_om->frag_end[n_fragment] = n_position - 1;
1219 wfm_om->frag_n_points[n_fragment] =
1220 wfm_om->frag_end[n_fragment]
1221 - wfm_om->frag_begin[n_fragment] + 1;
1222 wfm_om->n_point += wfm_om->frag_n_points[n_fragment];
1223 n_word++;
1224 }
1225 else
1226 return(ERROR_CORRUPTED_WF);
1227
1228 n_fragment++;
1229 } /* end while fragment */
1230
1231
1232 wfm_om->n_frag = n_fragment;
1233 if( !(n_word & 0x1) ) n_word++;
1234
1235 if(n_fragment >= MAX_N_OF_FRAGS) return(ERROR_MAX_N_FRAGMENTS_EXCEEDED);
1236
1237
1238 // Hack to get rid of last value of waveform always set to 0
1239 if (wfm_om->wfm_y[wfm_om->n_point] == 0.0)
1240 {
1241 // erase last point of waveform
1242 wfm_om->n_point--;
1243
1244 // Shorten last pulse if necessary
1245 // if( wfm_om.peak_end[wfm_om.n_peak-1]
1246 // == wfm_om.frag_end[wfm_om.n_frag-1] )
1247 // wfm_om.peak_end[wfm_om.n_peak-1]--;
1248
1249 // Shorten last fragment
1250 wfm_om->frag_n_points[wfm_om->n_frag-1]--;
1251 wfm_om->frag_end[wfm_om->n_frag-1]--;
1252
1253 wfm_om->wfm_min = 4095.0;
1254 wfm_om->wfm_max = 0.0;
1255 for (Int_t i_value=0; i_value < wfm_om->n_point; i_value++)
1256 {
1257 if (wfm_om->wfm_y[i_value] > wfm_om->wfm_max) wfm_om->wfm_max=wfm_om->wfm_y[i_value];
1258 if (wfm_om->wfm_y[i_value] < wfm_om->wfm_min) wfm_om->wfm_min=wfm_om->wfm_y[i_value];
1259 }
1260 }
1261
1262 return(debug);
1263}
1264///////////////////////////////////////////////////////////////////////////