Changeset 351 for trunk/MagicSoft/Simulation/Detector
- Timestamp:
- 02/08/00 12:50:36 (25 years ago)
- Location:
- trunk/MagicSoft/Simulation/Detector/include-MTrigger
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx
r307 r351 6 6 #include "MTrigger.hxx" 7 7 8 #include "TROOT.h" 9 #include "TFile.h" 10 #include "TH1.h" 11 #include "TObjArray.h" 12 #include "MGTriggerSignal.hxx" 13 14 15 MTrigger::MTrigger() { 16 17 FILE *unit_mtrig ; 18 Int_t endflag = 1 ; 19 char datac[256] ; 20 char dummy[50] ; 21 // 22 // default constructor 23 // 24 // The procedure is the following: 25 // 26 // 1. Allocation of some memory needed 27 // 2. some parameters of the trigger are set to default. 28 // 3. if a File MTrigger.card exists in the current directory, 29 // this parameters of the trigger may be changed 30 // 4. Then the all signals are set to zero 31 32 // 33 // allocate the memory for the 2dim arrays (a_sig, d_sig ) 34 // 35 36 for( Int_t j=0; j<TRIGGER_PIXELS; j++ ) { 37 38 a_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ; 39 40 d_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ; 41 } 42 43 // 44 // set the values for the standard response pulse 45 // 46 47 fwhm_resp = RESPONSE_FWHM ; 48 ampl_resp = RESPONSE_AMPLITUDE ; 49 50 chan_thres = CHANNEL_THRESHOLD ; 51 gate_leng = TRIGGER_GATE ; 52 trigger_multi = TRIGGER_MULTI ; 53 54 // 55 // check if the file MTrigger.card exists 56 // 57 58 if ( (unit_mtrig = fopen ("MTrigger.card", "r")) != 0 ) { 59 cout << "[MTrigger] use the values from MTrigger.card "<< endl ; 60 61 while ( endflag == 1 ) { 62 // 63 // 64 fgets (datac, 255, unit_mtrig) ; 65 // printf ("--> %s <--", datac ) ; 66 67 // 68 // now compare the line with controlcard words 69 // 70 71 if ( strncmp (datac, "channel_threshold", 17 ) == 0 ) { 72 sscanf (datac, "%s %f", dummy, &chan_thres ) ; 73 } 74 else if ( strncmp (datac, "gate_length", 11 ) == 0 ) { 75 sscanf (datac, "%s %f", dummy, &gate_leng ) ; 76 } 77 else if ( strncmp (datac, "response_fwhm", 13 ) == 0 ) { 78 sscanf (datac, "%s %f", dummy, &fwhm_resp ) ; 79 } 80 else if ( strncmp (datac, "response_ampl", 13 ) == 0 ) { 81 sscanf (datac, "%s %f", dummy, &l_resp ) ; 82 } 83 84 if ( feof(unit_mtrig) != 0 ) { 85 endflag = 0 ; 86 } 87 88 } 89 90 fclose ( unit_mtrig ) ; 91 } 92 else { 93 cout << "[MTrigger] use the standard values for MTrigger "<< endl ; 94 } 95 96 cout << endl 97 << "[MTrigger] Setting up the MTrigger with this values "<< endl ; 98 cout << endl 99 << "[MTrigger] ChannelThreshold: " << chan_thres << " mV" 100 << endl ; 101 102 cout << "[MTrigger] Gate Length: " << gate_leng << " ns" 103 << endl ; 104 cout << "[MTrigger] Response FWHM: " << fwhm_resp << " ns" 105 << endl ; 106 cout << "[MTrigger] Response Amplitude: " << ampl_resp << " mV" 107 << endl ; 108 109 cout << endl ; 110 // 111 // set up the response shape 112 // 113 Int_t i, ii ; 114 115 Float_t sigma ; 116 Float_t x, x0 ; 117 118 sigma = fwhm_resp / 2.35 ; 119 x0 = 3*sigma ; 120 121 for (i=0; i< RESPONSE_SLICES ; i++ ) { 122 123 x = i * (1./((Float_t)SLICES_PER_NSEC)) 124 + (1./( 2 * (Float_t)SLICES_PER_NSEC )) ; 125 126 sing_resp[i] = 127 ampl_resp * expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ; 128 129 // cout << i << " " 130 // << x << " " 131 // << sing_resp[i] 132 // << endl ; 133 134 } 135 136 // 137 // the amplitude of one single photo electron is not a constant. 138 // There exists a measured distribution from Razmik. This distribution 139 // is used to simulate the noise of the amplitude. 140 // For this a histogramm (histPmt) is created and filled with the 141 // values. 142 // 143 144 histPmt = new TH1F ("histPmt","Noise of PMT", 40, 0., 40.) ; 145 146 Stat_t ValRazmik[41] = { 0., 2.14, 2.06, 2.05, 2.05, 2.06, 2.07, 2.08, 2.15, 147 2.27, 2.40, 2.48, 2.55, 2.50, 2.35, 2.20, 2.10, 148 1.90, 1.65, 1.40, 1.25, 1.00, 0.80, 0.65, 0.50, 149 0.35, 0.27, 0.20, 0.18, 0.16, 0.14, 0.12, 0.10, 150 0.08, 0.06, 0.04, 0.02, 0.01, 0.005,0.003, 0.001} ; 151 152 histMean = histPmt->GetMean() ; 153 154 histPmt->SetContent( ValRazmik) ; 155 156 histMean = histPmt->GetMean() ; 157 158 // 159 // create the random generator for the Electronic Noise 160 // 161 162 GenElec = new TRandom() ; 163 164 165 // 166 // Read in the lookup table for NN trigger 167 // 168 169 FILE *unit ; 170 int id ; 171 float y ; 172 173 i = 0 ; 174 175 if ( (unit = fopen("../include-MTrigger/TABLE_NEXT_NEIGHBOUR", "r" )) == 0 ) { 176 cout << "ERROR: not able to read ../include-MTrigger/TABLE_NEXT_NEIGHBOUR" 177 << endl ; 178 exit(123) ; 179 } 180 else { 181 while ( i < TRIGGER_PIXELS ) 182 { 183 fscanf ( unit, " %d", &id ) ; 184 185 for ( Int_t k=0; k<6; k++ ) { 186 fscanf ( unit, "%d ", &NN[i][k] ) ; 187 } 188 i++ ; 189 } 190 191 fclose (unit) ; 192 } 193 194 195 // 196 // 197 // set all the booleans used to FALSE, indicating that the pixel is not 198 // used in this event. 199 // 200 201 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) { 202 used [i] = FALSE ; 203 204 nphot[i] = 0 ; 205 } 206 207 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 208 sum_d_sig[ii] = 0. ; 209 } 210 211 // 212 // set the information about the Different Level Triggers to zero 213 // 214 215 nZero = nFirst = nSecond = 0 ; 216 217 for ( i = 0 ; i < 5 ; i++) { 218 SlicesZero[i] = 0 ; 219 SlicesFirst[i] = 0 ; 220 SlicesSecond[i] = 0 ; 221 } 222 223 cout << " end of MTrigger::MTrigger()" << endl ; 224 } 225 226 MTrigger::~MTrigger() { 227 228 delete histPmt ; 229 } 230 231 void MTrigger::Reset() { 232 // 233 // set all values of the signals to zero 234 // 235 Int_t i, ii ; 236 237 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) { 238 used [i] = FALSE ; 239 dknt [i] = FALSE ; 240 241 nphot[i] = 0 ; 242 } 243 244 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 245 sum_d_sig[ii] = 0. ; 246 } 247 248 // 249 // set the information about the Different Level Triggers to zero 250 // 251 252 nZero = nFirst = nSecond = 0 ; 253 254 for ( i = 0 ; i < 5 ; i++) { 255 SlicesZero[i] = 0 ; 256 SlicesFirst[i] = 0 ; 257 SlicesSecond[i] = 0 ; 258 } 259 260 } 261 262 263 Float_t MTrigger::Fill( Int_t iPix, Float_t time ) { 264 // 265 // fills the information about one single Phe in the Trigger class 266 // 267 // parameter is the number of the pixel and the time-difference to the 268 // first particle 269 // 270 // 271 272 Int_t i, ichan ; 273 274 Float_t NoiseAmp = 0 ; // Amplitude of the PMT signal (results from noise) 275 276 // 277 // first we have to check if the pixel iPix is used or not until now 278 // if this is the first use, reset all signal for that pixels 279 // 280 if ( iPix >= CAMERA_PIXELS ) { 281 // 282 // the PixelID is greater than the CAMERA 283 // 284 cout << " WARNING: MTrigger::Fill() : iPix greater than CAMERA_PIXELS" 285 << endl ; 286 NoiseAmp = 0. ; 287 } 288 else if ( iPix >=TRIGGER_PIXELS ) { 289 // 290 // the pixel is inside the Camera, but outside of the TRIGGER-FIELD 291 // 292 // we just scramble the amplitude of the PMT-signal for the FADC 293 // 294 // scramble the Amplitude of this single photo electron signal 295 // 296 NoiseAmp = (histPmt->GetRandom()/histMean) ; 297 } 298 else { 299 // 300 // the photoelectron is contributing to the trigger 301 // 302 if ( used[iPix] == FALSE ) { 303 used [iPix] = TRUE ; 304 // baseline[iPix] = 0. ; 305 306 for (i=0; i < TRIGGER_TIME_SLICES; i++ ) { 307 a_sig[iPix][i] = 0. ; 308 d_sig[iPix][i] = 0. ; 309 } 310 } 311 312 // 313 // then select the time slice to use (ican) 314 // 315 316 317 if ( time < 0. ) { 318 cout << " WARNING!! " << time << " below ZERO!! Very strange!!" 319 << endl ; 320 } 321 else if ( time < TOTAL_TRIGGER_TIME ) { 322 nphot[iPix]++ ; 323 // 324 ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 325 326 // 327 // scramble the Amplitude of this single photo electron signal 328 // 329 NoiseAmp = (histPmt->GetRandom()/histMean) ; 330 331 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) { 332 333 if ( (ichan+i) < TRIGGER_TIME_SLICES ) { 334 a_sig[iPix][ichan+i] += NoiseAmp * sing_resp[i] ; 335 336 } 337 } 338 } 339 else { 340 cout << " WARNING!! " << time << " out of TriggerTimeRange " 341 << TOTAL_TRIGGER_TIME << endl ; 342 } 343 } 344 345 return NoiseAmp ; 346 347 } 348 349 350 Float_t MTrigger::FillNSB( Int_t iPix, Float_t time ) { 351 // 352 // fills the information about one single Phe in the Trigger class 353 // 354 // parameter is the number of the pixel and the time-difference to the 355 // first particle 356 // 357 // 358 359 Int_t i, ichan ; 360 361 Float_t NoiseAmp = 0 ; // Amplitude of the PMT signal (results from noise) 362 363 // 364 // first we have to check if the pixel iPix is used or not until now 365 // if this is the first use, reset all signal for that pixels 366 // 367 if ( iPix >= CAMERA_PIXELS ) { 368 cout << " WARNING: MTrigger::Fill() : iPix greater than CAMERA_PIXELS" 369 << endl ; 370 } 371 else if ( iPix >= TRIGGER_PIXELS ) { 372 // 373 // scramble the Amplitude of this single photo electron signal 374 // 375 NoiseAmp = (histPmt->GetRandom()/histMean) ; 376 } 377 378 else { 379 if ( used[iPix] == FALSE ) { 380 used [iPix] = TRUE ; 381 // baseline[iPix] = 0. ; 382 383 for (i=0; i < TRIGGER_TIME_SLICES; i++ ) { 384 a_sig[iPix][i] = 0. ; 385 d_sig[iPix][i] = 0. ; 386 } 387 } 388 389 // 390 // then select the time slice to use (ican) 391 // 392 393 if ( time < 0. ) { 394 cout << " WARNING!! " << time << " below ZERO!! Very strange!!" 395 << endl ; 396 } 397 else if ( time < TOTAL_TRIGGER_TIME ) { 398 // 399 // FillNSB doesn't add a photon to nphot[iPix] as the method Fill do!! 400 // 401 402 ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 403 404 // 405 // scramble the Amplitude of this single photo electron signal 406 // 407 NoiseAmp = (histPmt->GetRandom()/histMean) ; 408 409 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) { 410 411 if ( (ichan+i) < TRIGGER_TIME_SLICES ) { 412 a_sig[iPix][ichan+i] += NoiseAmp * sing_resp[i] ; 413 } 414 } 415 } 416 else { 417 cout << " WARNING!! " << time << " out of TriggerTimeRange " 418 << TOTAL_TRIGGER_TIME << endl ; 419 } 420 } 421 422 return NoiseAmp ; 423 424 } 425 426 void MTrigger::ElecNoise() { 427 428 Float_t rausch ; 429 430 rausch = RESPONSE_AMPLITUDE * 0.3 ; 431 432 for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++ ) { 433 if ( used [i] == TRUE ) { 434 //cout << "Pixel " << i << " used" ; 435 436 for ( Int_t ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 437 438 a_sig [i][ii] += GenElec->Gaus(0., rausch ) ; 439 440 } 441 } 442 } 443 444 } 445 446 447 Int_t MTrigger::Diskriminate() { 448 449 cout << " MTrigger::Diskriminate()" << flush ; 450 451 Int_t iM = 0 ; 452 Int_t i, ii ; 453 454 Int_t jmax = (Int_t) (gate_leng * SLICES_PER_NSEC ) ; 455 456 457 // 458 // first of all determine the integral of all signals to get 459 // the baseline shift. 460 // 461 462 463 for ( i=0 ; i < TRIGGER_PIXELS ; i++ ) { 464 if ( used[i] == TRUE ) { 465 baseline[i] = 0. ; 466 467 for ( ii = 0 ; ii < TRIGGER_TIME_SLICES ; ii++ ) { 468 baseline[i] += a_sig[i][ii] ; 469 } 470 471 baseline[i] = baseline[i] / ( (Float_t ) TRIGGER_TIME_SLICES) ; 472 473 //cout << "Pixel " << i 474 // << " baseline " << baseline[i] 475 // <<endl ; 476 477 } 478 } 479 480 // 481 // take only that pixel which are used 482 // 483 484 for ( i=0 ; i < TRIGGER_PIXELS; i++ ) { 485 if ( used [i] == TRUE ) { 486 //cout << "Pixel " << i << " used" ; 487 488 for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 489 490 // 491 // first check if the signal is crossing the CHANNEL_THRESHOLD 492 // form low to big signals 493 // 494 495 if ( a_sig[i][ii-1] < chan_thres && 496 a_sig[i][ii] >= chan_thres ) { 497 { 498 if ( dknt[i] == FALSE ) { 499 dknt [i] = TRUE ; 500 iM++ ; 501 } 502 // cout << " disk " << ii ; 503 // 504 // put the standard diskriminator signal in 505 // the diskriminated signal 506 // 507 for ( Int_t j=0 ; j < jmax ; j++ ) { 508 509 if ( ii+j < TRIGGER_TIME_SLICES ) { 510 d_sig [i][ii+j] = 1. ; 511 sum_d_sig [ii+j] += 1. ; 512 } 513 } 514 ii = ii + jmax ; 515 } 516 } 517 } 518 // cout << endl ; 519 } 520 } 521 522 //cout << "** MTrigger::Diskriminate() " << iM << endl ; 523 524 525 // 526 // determine the number of zero level triggers 527 // 528 // zero level trigger = the sum of all diskriminated signals 529 // is above the TRIGGER_MULTI value. 530 // only for this events it is neccessay to look for next neighbours!!! 531 // 532 533 if ( iM > TRIGGER_MULTI ) { 534 Int_t iReturn = 0 ; 535 536 for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 537 if ( sum_d_sig[ii] > TRIGGER_MULTI ) { 538 iReturn++ ; 539 540 SlicesZero[nZero++] = ii ; 541 542 // 543 // if a trigger occurs we read out the next 50 nsec 544 // 545 // -> don't study the next 50/0.25 = 200 slices 546 // 547 ii = ii + 200 ; 548 } 549 } 550 551 return ( iReturn ) ; 552 } 553 else { 554 return ( 0 ) ; 555 } 556 557 return ( 0 ) ; 558 559 } 560 561 Int_t MTrigger::FirstLevel() { 562 563 Int_t iReturn = 0 ; 564 565 Bool_t Muster[TRIGGER_PIXELS] ; 566 Int_t iMulti = 0 ; 567 568 // cout << "#### MTrigger::FirstLevel()" << endl ; 569 // cout << nZero << " " << SlicesZero[0] << endl ; 570 571 if ( nZero > 1 ) { 572 cout << " INFORMATION: more than one Zero Level TRIGGER " << endl ; 573 } 574 575 // 576 // loop over all ZeroLevel Trigger 577 // 578 // it is only neccessary to look after a ZeroLevel Trigger for 579 // a FirstLevel (NextNeighbour) trigger. 580 // 581 582 for (Int_t iloop = 0; iloop < nZero ; iloop++ ) { 583 584 // 585 // Then run over all slices 586 // start at the ZeroLevelTrigger slices 587 // 588 589 for ( Int_t iSli = SlicesZero[iloop]; 590 iSli < SlicesZero[iloop]+ 200; iSli++ ) { 591 592 // 593 // then look in all pixel if the diskriminated signal is 1 594 // 595 iMulti = 0 ; 596 597 for ( Int_t iPix = 0 ; iPix < TRIGGER_PIXELS; iPix++ ) { 598 Muster[iPix] = kFALSE ; 599 600 if ( used [iPix] == TRUE ) { 601 // 602 // now check the diskriminated signal 603 // 604 if ( d_sig [iPix][iSli] > 0. ) { 605 606 iMulti++ ; 607 Muster[iPix] = kTRUE ; 608 } 609 } 610 } // end of loop over the pixels 611 612 // 613 // here we have to look for next neighbours 614 // 615 616 if ( PassNextNeighbour ( Muster ) ) { 617 // 618 // A NN-Trigger is detected at time Slice 619 // 620 SlicesFirst[nFirst++] = iSli ; 621 iReturn++ ; 622 break ; 623 } 624 } // end of loop over the slices 625 626 } // end of loop over zerolevelTriggers 627 628 // 629 // return the Number of FirstLevel Triggers 630 // 631 return iReturn ; 632 } 633 634 635 Bool_t MTrigger::PassNextNeighbour ( Bool_t m[] ) { 636 // 637 // This method is looking for next neighbour triggers using a 638 // NNlookup table. This table is builded by the default constructor 639 // 640 641 Int_t iNN ; 642 643 // 644 // loop over all trigger pixels 645 // 646 for ( Int_t i=0; i<TRIGGER_PIXELS; i++) { 647 // 648 // check if this pixel has a diskrminator signal 649 // (this is inside m[] ) 650 // 651 652 if ( m[i] ) { 653 iNN = 1 ; 654 // cout << "/ " << i ; 655 656 // 657 // look in the next neighbours from the lookuptable 658 // 659 for ( Int_t kk=0; kk<6; kk++ ) { 660 // 661 // if the nextneighbour is outside the triggerarea do nothing 662 // 663 if (NN[i][kk] >= TRIGGER_PIXELS ) { 664 665 } 666 // the nextneighbout is inside the TRIGGER_PIXELS 667 else { 668 // 669 // look if the boolean of nn pixels is true 670 // 671 672 if ( m[ NN[i][kk] ] ) { 673 iNN++ ; 674 } 675 } 676 } 677 678 // cout << " NN " << iNN ; 679 680 if ( iNN >=4 ) { 681 return ( kTRUE ) ; 682 } 683 } 684 } 685 return ( kFALSE ) ; 686 } 687 688 Float_t MTrigger::GetFirstLevelTime(Int_t il ) { 689 return ( (Float_t)SlicesFirst[il]/ SLICES_PER_NSEC ) ; 690 } 691 692 693 694 void MTrigger::ShowSignal (MMcEvt *McEvt) { 695 // 696 // This method is used to book the histogramm to show the signal in 697 // a special gui frame (class MGTriggerSignal). After the look onto the 698 // signals for a better understanding of the things we will expect 699 // the gui frame and all histogramms will be destroyed. 700 // 701 702 // 703 // first of all create a list of the histograms to show 704 // 705 // take only that one with a entry 706 707 TH1F *hist ; 708 TH1F *dhist ; 709 Char_t dumm[10]; 710 Char_t name[256]; 711 712 TObjArray *AList ; 713 AList = new TObjArray(10) ; 714 715 TObjArray *DList ; 716 DList = new TObjArray(10) ; 717 718 // the list of analog signal histograms 719 // at the beginning we initalise 10 elements 720 // but this array expand automaticly if neccessay 721 722 Int_t ic = 0 ; 723 for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++ ) { 724 if ( used [i] == TRUE ) { 725 726 sprintf (dumm, "A_%d", i ) ; 727 sprintf (name, "analog %d", i ) ; 728 729 hist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME); 730 // 731 // fill the histogram 732 // 733 734 for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) { 735 hist->SetBinContent (ibin, a_sig[i][ibin-1]) ; 736 } 737 hist->SetMaximum(8.); 738 hist->SetStats(kFALSE); 739 740 AList->Add(hist) ; 741 742 sprintf (dumm, "D_%d", i ) ; 743 sprintf (name, "digital %d", i ) ; 744 745 dhist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME); 746 if ( dknt[i] == TRUE ) { 747 // 748 // fill the histogram of digital signal 749 // 750 for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) { 751 dhist->SetBinContent (ibin, d_sig[i][ibin-1]) ; 752 dhist->SetStats(kFALSE); 753 } 754 } 755 dhist->SetMaximum(1.5); 756 757 DList->Add(dhist); 758 759 ic++ ; 760 761 } 762 } 763 764 // 765 // create the Gui Tool 766 // 767 // 768 769 new MGTriggerSignal(McEvt, 770 AList, 771 DList, 772 gClient->GetRoot(), 773 gClient->GetRoot(), 774 400, 400 ) ; 775 776 // 777 // delete the List of histogramms 778 // 779 780 AList->Delete() ; 781 DList->Delete() ; 782 783 delete AList ; 784 delete DList ; 785 } 786 -
trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx
r307 r351 1 // 1 #ifndef __MTrigger__ 2 #define __MTrigger__ 3 2 4 // class MTrigger 3 5 // … … 12 14 #include <math.h> 13 15 16 #include "TROOT.h" 14 17 #include "TObject.h" 18 #include "TRandom.h" 19 #include "TH1.h" 15 20 16 21 #include "Mdefine.h" 22 #include "MMcEvt.h" 17 23 18 #define TRIGGER_TIME_SLICES 400 24 #include "MTriggerDefine.h" 25 26 27 //========== 28 // MTrigger 19 29 // 20 // We need 400 Time Slices of 0.25 nsec width. 21 // So the whole Time range we studies is 100 nsec. 30 // The simulation of the Trigger for MonteCarlo Events is using this 31 // class. So all methods concerning the trigger should be done inside this 32 // class. 22 33 // 23 #define RESPONSE_SLICES 40 34 // For a better understanding of the behavior of the trigger is here small 35 // abstract of the trigger. This may change in the future. 24 36 // 25 // This is for the standard response Signal to 1 Photoelectron 26 // that leaves the Photocathode 27 // The whole Timescale for the signal is 10 nsec 37 // 38 // We now from the camera program (This is the surrounding of the class 39 // MTrigger.) that one photo electron leaves at time t the photo cathode 40 // of the pixel number iPix). 41 // 42 // At the end of the PMT, the preamp, the optical fiber transmission we 43 // get a signal of a given shape. After some discussion with Eckart the 44 // standard response function looks like this : 45 // 46 // It is a gaussian Signal with a given FWHM. 47 // 48 // So whenever a photo electron leaves the photo cathod, on has to add 49 // the standard response function to the analog signal of the pixel. 50 // 51 // Each pixel of the camera has such an summed-up analog signal. It may 52 // look like this picture: 28 53 // 29 54 // 30 // These values are discussed with Eckart. We start from this point. 31 #define RESPONSE_FWHM 2. 32 #define RESPONSE_AMPLITUDE 1. 55 // This is the input of the discriminator for the pixels. The output of 56 // the discriminator is a digital signal. The response of the diskriminator 57 // is not fixed at the moment. There are discussion about this topic. 58 // 59 // At the moment the response is very simple. Whenever the analog signal 60 // is crossing a defined threshold from below to above, a digital signal 61 // with a given length is created. 62 // 63 // No one can start with the simulation of different trigger levels. 64 // 65 // The TriggerLevelZero is a very easy one. It is just looking if there 66 // are more then N digital signals at level ON (=1). If this is the case, 67 // a TriggerLevelZero signal is created. 33 68 // 34 // This are the Standard values of the response function for 35 // 1 photo electron. 36 // We assume a gaussian pulse with FWHM 2.5 nsec. 37 // 69 // The TriggerLevelOne is not implemented now. This will be a kind of next 70 // neighbour condition (i.e. four neigbouring analog signals at the same 71 // time, but this requests at least four digital signals at level ON, what 72 // is equivalent with a TriggerLevelZero. 73 // 74 // 75 class MTrigger { 38 76 39 #define CHANNEL_THRESHOLD 2. 40 // 41 // This is the diskriminator threshold for each individual channel 42 // First we set the value to 2 unit of the RESPONSE_AMPLITUDE 43 // 44 #define TRIGGER_GATE 3. 45 // 46 // Here we set the width of the digital signal we get if the signal 47 // passes the diskriminator 48 // 49 #define TRIGGER_MULTI 4. 50 // 51 // We get a Level Zero Trigger, if we have a least TRIGGER_MULTI 52 // channels with a diskrimiator signal at the same time 53 // 77 private: 78 // 79 // then for all pixels the shape of all the analog signals 80 // 81 Bool_t used [TRIGGER_PIXELS] ; // a boolean to indicated if the pixels is used in this event 82 Int_t nphot[TRIGGER_PIXELS]; // count the photo electrons per pixel (NSB phe are not counted) 83 84 Float_t *a_sig[TRIGGER_PIXELS] ; // the analog signal for pixels 54 85 86 Float_t baseline[TRIGGER_PIXELS] ; // for the baseline shift 87 88 // 89 // then for all pixels the shape of the digital signal 90 // 91 Bool_t dknt [TRIGGER_PIXELS] ; // a boolean to indicated if the pixels has passed the diskrminator 92 Float_t *d_sig[TRIGGER_PIXELS] ; // the digital signal for all pixels 93 94 // 95 // and the sum of all digital signals 96 // 97 Float_t sum_d_sig[TRIGGER_TIME_SLICES] ; 98 99 100 // 101 // first the data for the response function 102 // 103 Float_t fwhm_resp ; // fwhm of the phe_response function 104 Float_t ampl_resp ; // amplitude of the phe_response function (in mV) 105 Float_t sing_resp[ RESPONSE_SLICES ] ; // the shape of the phe_response function 106 107 TH1F *histPmt ; 108 Float_t histMean ; // Mean value of the distribution of Rasmik (stored in histPmt) 109 TRandom *GenElec ; // RandomGenerator for the Electronic Noise 110 111 // 112 // some values for the trigger settings 113 // 114 115 Float_t chan_thres ; // the threshold (in mV) for each individuel pixels 116 Float_t gate_leng ; // the length of the digital signal if analog signal is above threshold 117 118 Float_t trigger_multi ; // Number of Pixels requested for a Trigger 119 120 // 121 // The lookup table for the next neighbours 122 // 123 124 Int_t NN[TRIGGER_PIXELS][6] ; 125 126 // 127 // some information about the different TriggerLevels in each Event 128 // 129 130 Int_t nZero ; // how many ZeroLevel Trigger in one Event 131 Int_t SlicesZero[5] ; // Times Slices at which the ZeroLevel Triggers occur 132 133 Int_t nFirst ; // how many FirstLevel Trigger in one Event 134 Int_t SlicesFirst[5] ; // Times Slices at which the FirstLevel Triggers occur 135 136 Int_t nSecond ; // how many SecondLevel Trigger in one Event 137 Int_t SlicesSecond[5] ; // Times Slices at which the SecondLevel Triggers occur 138 139 140 public: 141 142 MTrigger() ; 143 144 ~MTrigger() ; 145 146 void Reset() ; 147 148 Float_t Fill( Int_t, Float_t ) ; 149 150 Float_t FillNSB( Int_t, Float_t ) ; 151 152 void ElecNoise() ; 153 154 Int_t Diskriminate() ; 155 156 Int_t FirstLevel() ; 157 158 Bool_t PassNextNeighbour( Bool_t m[] ) ; 159 160 void ShowSignal (MMcEvt *McEvt) ; 161 162 Float_t GetFirstLevelTime( Int_t il ) ; 163 164 } ; 165 166 #endif 167
Note:
See TracChangeset
for help on using the changeset viewer.