Changeset 373 for trunk/MagicSoft/Simulation
- Timestamp:
- 03/13/00 09:12:26 (25 years ago)
- Location:
- trunk/MagicSoft/Simulation/Detector/include-MTrigger
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx
r372 r373 14 14 15 15 MTrigger::MTrigger() { 16 17 FILE *unit_mtrig ; 18 Int_t endflag = 1 ; 19 char datac[256] ; 20 char dummy[50] ; 16 // ============================================================ 21 17 // 22 18 // default constructor … … 29 25 // this parameters of the trigger may be changed 30 26 // 4. Then the all signals are set to zero 31 27 28 FILE *unit_mtrig ; 29 Int_t endflag = 1 ; 30 char datac[256] ; 31 char dummy[50] ; 32 33 Float_t threshold ; 34 32 35 // 33 36 // allocate the memory for the 2dim arrays (a_sig, d_sig ) … … 47 50 fwhm_resp = RESPONSE_FWHM ; 48 51 ampl_resp = RESPONSE_AMPLITUDE ; 49 50 chan_thres = CHANNEL_THRESHOLD ; 51 gate_leng = TRIGGER_GATE ; 52 trigger_multi = TRIGGER_MULTI ; 53 52 53 threshold = CHANNEL_THRESHOLD ; 54 55 56 gate_leng = TRIGGER_GATE ; 57 trigger_multi = TRIGGER_MULTI ; 58 trigger_geometry = TRIGGER_GEOM ; 59 54 60 // 55 61 // check if the file MTrigger.card exists … … 70 76 71 77 if ( strncmp (datac, "channel_threshold", 17 ) == 0 ) { 72 sscanf (datac, "%s %f", dummy, & chan_thres ) ;78 sscanf (datac, "%s %f", dummy, &threshold ) ; 73 79 } 74 80 else if ( strncmp (datac, "gate_length", 11 ) == 0 ) { … … 80 86 else if ( strncmp (datac, "response_ampl", 13 ) == 0 ) { 81 87 sscanf (datac, "%s %f", dummy, &l_resp ) ; 88 } 89 else if ( strncmp (datac, "multiplicity", 12 ) == 0 ) { 90 sscanf (datac, "%s %f", dummy, &trigger_multi ) ; 91 } 92 else if ( strncmp (datac, "topology", 8 ) == 0 ) { 93 sscanf (datac, "%s %i", dummy, &trigger_geometry ) ; 82 94 } 83 95 … … 97 109 << "[MTrigger] Setting up the MTrigger with this values "<< endl ; 98 110 cout << endl 99 << "[MTrigger] ChannelThreshold: " << chan_thres<< " mV"111 << "[MTrigger] ChannelThreshold: " << threshold << " mV" 100 112 << endl ; 101 113 … … 106 118 cout << "[MTrigger] Response Amplitude: " << ampl_resp << " mV" 107 119 << endl ; 120 cout << "[MTrigger] Trigger Multiplicity: " << trigger_multi << " pixels" 121 << endl ; 122 cout << "[MTrigger] Trigger Topology: " << trigger_geometry 123 << endl ; 108 124 109 125 cout << endl ; 126 127 128 // 129 // we have introduced individual thresholds for all pixels 130 // 131 for (Int_t k=0; k<TRIGGER_PIXELS; k++ ) { 132 chan_thres[k] = threshold ; 133 } 134 110 135 // 111 136 // set up the response shape … … 132 157 // << endl ; 133 158 134 } 159 160 } 161 162 // 163 // look for the time between start of response function and the 164 // maximum value of the response function. This is needed by the 165 // member functions FillNSB() and FillStar() 166 // 167 168 Int_t imax = 0 ; 169 Float_t max = 0. ; 170 for (i=0; i< RESPONSE_SLICES ; i++ ) { 171 if ( sing_resp[i] > max ) { 172 imax = i ; 173 max = sing_resp[i] ; 174 } 175 } 176 177 peak_time = ( (Float_t) imax ) / ( (Float_t) SLICES_PER_NSEC ) ; 178 135 179 136 180 // … … 162 206 GenElec = new TRandom() ; 163 207 164 165 208 // 166 209 // Read in the lookup table for NN trigger … … 169 212 FILE *unit ; 170 213 int id ; 171 float y ;172 214 173 215 i = 0 ; … … 201 243 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) { 202 244 used [i] = FALSE ; 203 204 nphot[i] = 0 ; 245 dknt [i] = FALSE ; 246 247 nphotshow[i] = 0 ; 248 nphotnsb [i] = 0 ; 249 nphotstar[i] = 0 ; 250 251 baseline[i] = 0 ; 205 252 } 206 253 … … 209 256 } 210 257 258 // 259 // set the information about the Different Level Triggers to zero 260 // 261 262 nZero = nFirst = nSecond = 0 ; 263 264 for (ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 265 SlicesZero[ii] = FALSE; 266 } 267 268 for ( i = 0 ; i < 5 ; i++) { 269 SlicesFirst[i] = 0 ; 270 SlicesSecond[i] = 0 ; 271 } 272 cout << " end of MTrigger::MTrigger()" << endl ; 273 } 274 275 MTrigger::~MTrigger() { 276 // ============================================================// 277 // destructor 278 // 279 int i; 280 // delete histPmt ; 281 for(i=0;i<TRIGGER_PIXELS;i++){ 282 delete [] a_sig[i]; 283 delete [] d_sig[i]; 284 } 285 delete GenElec; 286 } 287 288 289 void MTrigger::Reset() { 290 // ============================================================ 291 // 292 // reset all values of the signals to zero 293 // 294 Int_t i, ii ; 295 296 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) { 297 used [i] = FALSE ; 298 dknt [i] = FALSE ; 299 300 nphotshow[i] = 0 ; 301 nphotnsb [i] = 0 ; 302 nphotstar[i] = 0 ; 303 } 304 305 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 306 sum_d_sig[ii] = 0. ; 307 } 308 211 309 // 212 310 // set the information about the Different Level Triggers to zero … … 220 318 SlicesSecond[i] = 0 ; 221 319 } 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 (" << iPix 285 <<")greater than CAMERA_PIXELS" 286 << endl ; 287 NoiseAmp = 0. ; 288 } 289 else if ( iPix >=TRIGGER_PIXELS ) { 290 // 291 // the pixel is inside the Camera, but outside of the TRIGGER-FIELD 292 // 293 // we just scramble the amplitude of the PMT-signal for the FADC 294 // 295 // scramble the Amplitude of this single photo electron signal 296 // 297 NoiseAmp = (histPmt->GetRandom()/histMean) ; 298 } 299 else { 300 // 301 // the photoelectron is contributing to the trigger 302 // 320 321 } 322 323 Float_t MTrigger::FillShow(Int_t iPix, Float_t time) { 324 // ============================================================ 325 // 326 // Fills the information of one single Phe electron that 327 // comes from the shower 328 // 329 330 // 331 // First check the time 332 // 333 334 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) { 335 cout << " WARNING: time of phe out of time range: " << time << endl; 336 return 0. ; 337 } 338 else { 339 return ( Fill( iPix, time, CASE_SHOW ) ) ; 340 } 341 } 342 343 Float_t MTrigger::FillNSB(Int_t iPix, Float_t time) { 344 // ============================================================ 345 // 346 // Fills the information of one single Phe electron that 347 // comes from the shower 348 // 349 350 // 351 // First check the time 352 // 353 354 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) { 355 cout << " WARNING: time of phe out of time range: " << time << endl; 356 return 0. ; 357 } 358 else { 359 return ( Fill( iPix, time - peak_time, CASE_NSB ) ) ; 360 } 361 } 362 363 Float_t MTrigger::FillStar(Int_t iPix, Float_t time) { 364 // ============================================================ 365 // 366 // Fills the information of one single Phe electron that 367 // comes from the shower 368 // 369 370 // 371 // First check the time 372 // 373 374 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) { 375 cout << " WARNING: time of phe out of time range: " << time << endl; 376 return 0. ; 377 } 378 else { 379 return ( Fill( iPix, time - peak_time, CASE_STAR ) ) ; 380 } 381 } 382 383 Float_t MTrigger::Fill( Int_t iPix, Float_t time, Int_t fall ) { 384 // ============================================================ 385 // 386 // Fills the information in the array for the analog signal 387 // 388 389 Float_t PmtAmp = 0 ; // Amplitude of the PMT signal (results from noise) 390 391 if ( iPix < 0 ) { 392 cout << " ERROR: in MTrigger::Fill() " << endl ; 393 cout << " ERROR: Pixel Id < 0 ---> Exit " << endl ; 394 exit (1) ; 395 } 396 else if ( iPix >= CAMERA_PIXELS ) { 397 cout << " ERROR: in MTrigger::Fill() " << endl ; 398 cout << " ERROR: Pixel Id > CAMERA_PIXELS ---> Exit " << endl ; 399 exit (1) ; 400 } 401 else if ( iPix >= TRIGGER_PIXELS ) { 402 // 403 // We have not to fill information in the trigger part, 404 // but we must create the height of the puls going into 405 // the FADC simulation 406 // 407 PmtAmp = (histPmt->GetRandom()/histMean) ; 408 409 // 410 // But we fill the information in the counters of phe's 411 // 412 413 if ( fall == CASE_SHOW ) 414 nphotshow[iPix]++ ; 415 else if ( fall == CASE_NSB ) 416 nphotshow[iPix]++ ; 417 else if ( fall == CASE_STAR ) 418 nphotstar[iPix]++ ; 419 420 421 } 422 else { 423 // 424 // we have a trigger pixel and we fill it 425 // 426 Int_t i ; 427 428 // 429 // but at the beginning we must check if this pixel is 430 // hitted the first time 431 // 432 303 433 if ( used[iPix] == FALSE ) { 304 434 used [iPix] = TRUE ; 305 435 // baseline[iPix] = 0. ; 306 436 307 437 for (i=0; i < TRIGGER_TIME_SLICES; i++ ) { 308 438 a_sig[iPix][i] = 0. ; … … 312 442 313 443 // 314 // then select the time slice to use (ican) 315 // 316 317 318 if ( time < 0. ) { 319 cout << " WARNING!! " << time << " below ZERO!! Very strange!!" 320 << endl ; 444 // get the randomized amplitude 445 // 446 PmtAmp = (histPmt->GetRandom()/histMean) ; 447 448 // 449 // select the first slice to fill 450 // 451 452 Int_t ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 453 454 // 455 // look over the response signal and put it in the signal line 456 // 457 458 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) { 459 460 if ( (ichan+i) >= 0 && 461 (ichan+i) < TRIGGER_TIME_SLICES ) { 462 a_sig[iPix][ichan+i] += PmtAmp * sing_resp[i] ; 463 } 321 464 } 322 else if ( time < TOTAL_TRIGGER_TIME ) { 323 nphot[iPix]++ ; 324 // 325 ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 326 327 // 328 // scramble the Amplitude of this single photo electron signal 329 // 330 NoiseAmp = (histPmt->GetRandom()/histMean) ; 331 332 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) { 333 334 if ( (ichan+i) < TRIGGER_TIME_SLICES ) { 335 a_sig[iPix][ichan+i] += NoiseAmp * sing_resp[i] ; 336 337 } 338 } 339 } 340 else { 341 cout << " WARNING!! " << time << " out of TriggerTimeRange " 342 << TOTAL_TRIGGER_TIME << endl ; 343 } 344 } 345 346 return NoiseAmp ; 347 348 } 349 350 351 Float_t MTrigger::FillNSB( Int_t iPix, Float_t time ) { 352 // 353 // fills the information about one single Phe in the Trigger class 354 // 355 // parameter is the number of the pixel and the time-difference to the 356 // first particle 357 // 358 // 359 360 Int_t i, ichan ; 361 362 Float_t NoiseAmp = 0 ; // Amplitude of the PMT signal (results from noise) 363 364 // 365 // first we have to check if the pixel iPix is used or not until now 366 // if this is the first use, reset all signal for that pixels 367 // 368 if ( iPix >= CAMERA_PIXELS ) { 369 cout << " WARNING: MTrigger::Fill() : iPix greater than CAMERA_PIXELS" 370 << endl ; 371 } 372 else if ( iPix >= TRIGGER_PIXELS ) { 373 // 374 // scramble the Amplitude of this single photo electron signal 375 // 376 NoiseAmp = (histPmt->GetRandom()/histMean) ; 377 } 378 379 else { 380 if ( used[iPix] == FALSE ) { 381 used [iPix] = TRUE ; 382 // baseline[iPix] = 0. ; 383 384 for (i=0; i < TRIGGER_TIME_SLICES; i++ ) { 385 a_sig[iPix][i] = 0. ; 386 d_sig[iPix][i] = 0. ; 387 } 388 } 389 390 // 391 // then select the time slice to use (ican) 392 // 393 394 if ( time < 0. ) { 395 cout << " WARNING!! " << time << " below ZERO!! Very strange!!" 396 << endl ; 397 } 398 else if ( time < TOTAL_TRIGGER_TIME ) { 399 // 400 // FillNSB doesn't add a photon to nphot[iPix] as the method Fill do!! 401 // 402 403 ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 404 405 // 406 // scramble the Amplitude of this single photo electron signal 407 // 408 NoiseAmp = (histPmt->GetRandom()/histMean) ; 409 410 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) { 411 412 if ( (ichan+i) < TRIGGER_TIME_SLICES ) { 413 a_sig[iPix][ichan+i] += NoiseAmp * sing_resp[i] ; 414 } 415 } 416 } 417 else { 418 cout << " WARNING!! " << time << " out of TriggerTimeRange " 419 << TOTAL_TRIGGER_TIME << endl ; 420 } 421 } 422 423 return NoiseAmp ; 424 425 } 465 466 // 467 // we fill the information in the counters of phe's 468 // 469 470 if ( fall == CASE_SHOW ) 471 nphotshow[iPix]++ ; 472 else if ( fall == CASE_NSB ) 473 nphotshow[iPix]++ ; 474 else if ( fall == CASE_STAR ) 475 nphotstar[iPix]++ ; 476 477 // 478 // 479 return PmtAmp ; 480 } 481 return PmtAmp ; 482 } 483 484 426 485 427 486 void MTrigger::ElecNoise() { 428 487 // ============================================================ 488 // 489 // adds the noise due to optronic and electronic 490 // to the signal 491 // 429 492 Float_t rausch ; 430 493 … … 442 505 } 443 506 } 444 445 } 446 447 448 Int_t MTrigger::Diskriminate() { 449 450 // cout << " MTrigger::Diskriminate()" << flush ; 451 507 } 508 509 void MTrigger::Diskriminate() { 510 // ============================================================ 511 // 512 // Diskriminates the analog signal 513 // 514 // one very important part is the calucaltion of the baseline 515 // shift. Because of the AC coupling of the PMT, only the 516 // fluctuations are interesting. If there are a lot of phe, 517 // a so-called shift of the baseline occurs. 518 // 519 452 520 Int_t iM = 0 ; 453 521 Int_t i, ii ; 454 522 523 455 524 Int_t jmax = (Int_t) (gate_leng * SLICES_PER_NSEC ) ; 456 457 525 458 526 // … … 461 529 // 462 530 463 464 531 for ( i=0 ; i < TRIGGER_PIXELS ; i++ ) { 465 532 if ( used[i] == TRUE ) { … … 472 539 baseline[i] = baseline[i] / ( (Float_t ) TRIGGER_TIME_SLICES) ; 473 540 474 cout << "Pixel " << i 475 << " baseline " << baseline[i] 476 <<endl ; 477 541 // cout << "Pixel " << i << " baseline " << baseline[i] <<endl ; 542 543 // 544 // now correct the baseline shift in the analog signal!! 545 // 478 546 for ( ii = 0 ; ii < TRIGGER_TIME_SLICES ; ii++ ) { 479 547 a_sig[i][ii] = a_sig[i][ii] - baseline[i] ; … … 482 550 } 483 551 552 // 553 // now the diskrimination is coming 484 554 // 485 555 // take only that pixel which are used … … 488 558 for ( i=0 ; i < TRIGGER_PIXELS; i++ ) { 489 559 if ( used [i] == TRUE ) { 490 //cout << "Pixel " << i << " used" ; 491 560 492 561 for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 493 494 562 // 495 563 // first check if the signal is crossing the CHANNEL_THRESHOLD … … 497 565 // 498 566 499 if ( a_sig[i][ii-1] < chan_thres &&500 a_sig[i][ii] >= chan_thres ) {567 if ( a_sig[i][ii-1] < chan_thres[i] && 568 a_sig[i][ii] >= chan_thres[i] ) { 501 569 { 502 570 if ( dknt[i] == FALSE ) { … … 513 581 if ( ii+j < TRIGGER_TIME_SLICES ) { 514 582 d_sig [i][ii+j] = 1. ; 515 sum_d_sig [ii+j] += 1. ;516 583 } 517 584 } … … 519 586 } 520 587 } 521 } 522 // cout << endl ;588 else d_sig[i][ii]=0.; 589 } 523 590 } 524 } 525 526 //cout << "** MTrigger::Diskriminate() " << iM << endl ; 527 528 529 // 530 // determine the number of zero level triggers 531 // 532 // zero level trigger = the sum of all diskriminated signals 533 // is above the TRIGGER_MULTI value. 534 // only for this events it is neccessay to look for next neighbours!!! 535 // 536 537 if ( iM > TRIGGER_MULTI ) { 538 Int_t iReturn = 0 ; 539 540 for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 541 if ( sum_d_sig[ii] > TRIGGER_MULTI ) { 542 iReturn++ ; 543 544 SlicesZero[nZero++] = ii ; 545 546 // 547 // if a trigger occurs we read out the next 50 nsec 548 // 549 // -> don't study the next 50/0.25 = 200 slices 550 // 551 ii = ii + 200 ; 552 } 553 } 554 555 return ( iReturn ) ; 556 } 557 else { 558 return ( 0 ) ; 559 } 560 561 return ( 0 ) ; 562 563 } 564 565 Int_t MTrigger::FirstLevel() { 566 567 Int_t iReturn = 0 ; 568 569 Bool_t Muster[TRIGGER_PIXELS] ; 570 Int_t iMulti = 0 ; 571 572 // cout << "#### MTrigger::FirstLevel()" << endl ; 573 // cout << nZero << " " << SlicesZero[0] << endl ; 574 575 if ( nZero > 1 ) { 576 cout << " INFORMATION: more than one Zero Level TRIGGER " << endl ; 577 } 578 579 // 580 // loop over all ZeroLevel Trigger 581 // 582 // it is only neccessary to look after a ZeroLevel Trigger for 583 // a FirstLevel (NextNeighbour) trigger. 584 // 585 586 for (Int_t iloop = 0; iloop < nZero ; iloop++ ) { 587 588 // 589 // Then run over all slices 590 // start at the ZeroLevelTrigger slices 591 // 592 593 for ( Int_t iSli = SlicesZero[iloop]; 594 iSli < SlicesZero[iloop]+ 200; iSli++ ) { 595 596 // 597 // then look in all pixel if the diskriminated signal is 1 598 // 599 iMulti = 0 ; 600 601 for ( Int_t iPix = 0 ; iPix < TRIGGER_PIXELS; iPix++ ) { 602 Muster[iPix] = kFALSE ; 603 604 if ( used [iPix] == TRUE ) { 605 // 606 // now check the diskriminated signal 607 // 608 if ( d_sig [iPix][iSli] > 0. ) { 609 610 iMulti++ ; 611 Muster[iPix] = kTRUE ; 612 } 613 } 614 } // end of loop over the pixels 615 616 // 617 // here we have to look for next neighbours 618 // 619 620 if ( PassNextNeighbour ( Muster ) ) { 621 // 622 // A NN-Trigger is detected at time Slice 623 // 624 SlicesFirst[nFirst++] = iSli ; 625 iReturn++ ; 626 break ; 627 } 628 } // end of loop over the slices 629 630 } // end of loop over zerolevelTriggers 631 632 // 633 // return the Number of FirstLevel Triggers 634 // 635 return iReturn ; 636 } 637 638 639 Bool_t MTrigger::PassNextNeighbour ( Bool_t m[] ) { 640 // 641 // This method is looking for next neighbour triggers using a 642 // NNlookup table. This table is builded by the default constructor 643 // 644 645 Int_t iNN ; 646 647 // 648 // loop over all trigger pixels 649 // 650 for ( Int_t i=0; i<TRIGGER_PIXELS; i++) { 651 // 652 // check if this pixel has a diskrminator signal 653 // (this is inside m[] ) 654 // 655 656 if ( m[i] ) { 657 iNN = 1 ; 658 // cout << "/ " << i ; 659 660 // 661 // look in the next neighbours from the lookuptable 662 // 663 for ( Int_t kk=0; kk<6; kk++ ) { 664 // 665 // if the nextneighbour is outside the triggerarea do nothing 666 // 667 if (NN[i][kk] >= TRIGGER_PIXELS ) { 668 669 } 670 // the nextneighbout is inside the TRIGGER_PIXELS 671 else { 672 // 673 // look if the boolean of nn pixels is true 674 // 675 676 if ( m[ NN[i][kk] ] ) { 677 iNN++ ; 678 } 679 } 680 } 681 682 // cout << " NN " << iNN ; 683 684 if ( iNN >=4 ) { 685 return ( kTRUE ) ; 686 } 687 } 688 } 689 return ( kFALSE ) ; 690 } 691 692 Float_t MTrigger::GetFirstLevelTime(Int_t il ) { 693 return ( (Float_t)SlicesFirst[il]/ SLICES_PER_NSEC ) ; 694 } 695 591 } 592 } 696 593 697 594 698 595 void MTrigger::ShowSignal (MMcEvt *McEvt) { 596 // ============================================================ 699 597 // 700 598 // This method is used to book the histogramm to show the signal in … … 790 688 } 791 689 690 691 Int_t MTrigger::ZeroLevel() { 692 // ============================================================ 693 // 694 // This is a level introduced just to speed up the program. 695 // It makes sense to look for next neighbours only if there 696 // are at least trigger_multi pixels with a diskriminator 697 // signal. 698 // 699 700 // 701 // first count the pixels with a diskriminator signal 702 // 703 Int_t iMul = 0 ; 704 for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) { 705 // 706 // 707 if ( dknt[iP] == TRUE ) { 708 iMul++ ; 709 } 710 } 711 712 // 713 // only if there are at least more pixels than requested 714 // it make sense to look into details 715 if ( iMul >= trigger_multi ) { 716 // 717 // fill the sum signal of all diskriminator signals 718 // 719 for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) { 720 // 721 // 722 if ( dknt[iP] == TRUE ) { 723 // 724 // sum it up 725 // 726 for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) { 727 // 728 // 729 sum_d_sig [iS] += d_sig[iP][iS] ; 730 } 731 } 732 } 733 // 734 // run over the sum_d_sig and check each time slice 735 // 736 Int_t iReturn = 0 ; 737 738 for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) { 739 740 if ( sum_d_sig[iS] >= trigger_multi ) { 741 iReturn++ ; 742 nZero++; 743 SlicesZero[iS] = TRUE ; 744 745 } 746 else SlicesZero[iS] = FALSE; 747 } 748 749 return ( iReturn ) ; 750 } 751 else { 752 return 0 ; 753 } 754 } 755 756 Int_t MTrigger::FirstLevel() { 757 //================================================= 758 // 759 // This is a level trigger which can look for several 760 // multiplicities (trigger_multi) 761 // and topologies (trigger_geometry) 762 // 763 764 Int_t iReturn = 0 ; // Return value for this function 765 766 if ( nZero > 1 ) { 767 cout << " INFORMATION: more than one Zero Level TRIGGER " << endl ; 768 } 769 770 // Definition of needed variables 771 Bool_t Muster[TRIGGER_PIXELS] ; 772 Bool_t Neighb[TRIGGER_PIXELS] ; 773 Int_t iMulti = 0 ; 774 775 // We put several wrong topologies which we already know that they 776 // are not possible. It can save time. 777 778 if (trigger_geometry==0 && trigger_multi>7) { 779 cout <<"You are lookiny for a topology that needs more than six neighbours of the same pixel"<<endl; 780 cout <<" Topology "<<trigger_geometry<<" Multiplicity "<<trigger_multi<<endl;; 781 return (kFALSE); 782 } 783 784 if (trigger_geometry==2 && trigger_multi<3) { 785 cout<<"Closed pack geometry with multiplicity "<<trigger_multi<<" does not make sense"<<endl; 786 return (kFALSE); 787 } 788 if (trigger_geometry>2) { 789 cout << "This trigger topology is not implemented"<<endl; 790 return (kFALSE); 791 } 792 793 // 794 // loop over all ZeroLevel Trigger 795 // 796 // it is only neccessary to look after a ZeroLevel Trigger for 797 // a FirstLevel (NextNeighbour) trigger. 798 // 799 800 if (nZero) { 801 802 // 803 // Then run over all slices 804 // 805 806 for ( Int_t iSli = 0; 807 iSli < TRIGGER_TIME_SLICES; iSli++ ) { 808 809 // Check if this time slice has more fired pixels than trigger_multi 810 811 if (SlicesZero[iSli]){ 812 // 813 // then look in all pixel if the diskriminated signal is 1 814 // 815 816 for ( Int_t iPix = 0 ; iPix < TRIGGER_PIXELS; iPix++ ) { 817 Muster[iPix] = kFALSE ; 818 Neighb[iPix] = kFALSE ; 819 if ( used [iPix] == TRUE ) { 820 // 821 // now check the diskriminated signal 822 // 823 if ( d_sig [iPix][iSli] > 0. ) { 824 825 Muster[iPix] = kTRUE ; 826 } 827 } 828 } // end of loop over the pixels 829 830 // 831 // here we have to look for the topologies 832 // 833 834 switch(trigger_geometry){ 835 case 0:{ 836 837 // It looks for a pixel above threshold which has 838 // trigger_multi-1 neighbour pixels above threshold 839 840 Bool_t Dummy[TRIGGER_PIXELS] ; 841 842 // Loop over all pixels 843 for (int j=0;j<TRIGGER_PIXELS;j++){ 844 Dummy=Muster; 845 for (int k=0; k<TRIGGER_PIXELS; k++){ 846 Neighb[k]=kFALSE; 847 } 848 if(Muster[j]){ 849 // If pixel is fired, it checks how many fired neighbours it has 850 for (iMulti=1;iMulti<trigger_multi; iMulti++) { 851 Neighb[j] = kTRUE ; 852 Dummy[j] = kTRUE ; 853 if (!PassNextNeighbour(Dummy, &Neighb[0])){ 854 break; 855 } 856 for (int k=0; k<TRIGGER_PIXELS; k++){ 857 if (Neighb[k]){ 858 Dummy[k]=kFALSE; 859 Neighb[k]=kFALSE; 860 } 861 } 862 } 863 if (iMulti==trigger_multi ) { 864 // 865 // A NN-Trigger is detected at time Slice 866 // 867 SlicesFirst[nFirst++] = iSli ; // We save time when it triggers 868 iReturn++ ; 869 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time) 870 break ; 871 } 872 } 873 } 874 break; 875 }; 876 877 case 1:{ 878 879 // It looks for trigger_multi neighbour pixels above the 880 // threshold. 881 882 for (int j=0;j<TRIGGER_PIXELS;j++){ 883 if(Muster[j]){ 884 // It checks if you can find 885 // trigger_multi fired neighbour pixels 886 Neighb[j] = kTRUE ; 887 for (iMulti=1;iMulti<trigger_multi; iMulti++) { 888 if (!PassNextNeighbour(Muster, &Neighb[0])) 889 break; 890 } 891 if (iMulti==trigger_multi ) { 892 // 893 // A NN-Trigger is detected at time Slice 894 // 895 SlicesFirst[nFirst++] = iSli ; // We save when it triggers 896 iReturn++ ; 897 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time) 898 break ; 899 } 900 else { 901 // We put Neighb to kFALSE to check an other pixel 902 for (int k=0; k<TRIGGER_PIXELS; k++){ 903 if (Neighb[k]){ 904 Neighb[k]=kFALSE; 905 } 906 } 907 } 908 } 909 } 910 break; 911 }; 912 case 2:{ 913 914 // It looks for trigger_multi closed pack neighbours 915 // above threshold 916 // Closed pack means that you can take out any pixel 917 // and you will still get a trigger for trigger_multi -1 918 919 Int_t closed_pack = 1; 920 921 for (int j=0;j<TRIGGER_PIXELS;j++){ 922 if(Muster[j]){ 923 // It checks if there are trigger_multi 924 // neighbours above threshold 925 Neighb[j] = kTRUE ; 926 for (iMulti=1;iMulti<trigger_multi; iMulti++){ 927 if (!PassNextNeighbour(Muster, &Neighb[0])) 928 break; 929 } 930 if (iMulti==trigger_multi ) { 931 // 932 // A NN-Trigger is detected at time Slice 933 // 934 935 // Check if there is closed pack topology 936 Bool_t Aux1[TRIGGER_PIXELS]; 937 Bool_t Aux2[TRIGGER_PIXELS]; 938 for (int jj=0;jj<TRIGGER_PIXELS;jj++) 939 Aux2[jj]=kFALSE; 940 for (int i=0;i<TRIGGER_PIXELS;i++){ 941 if (Neighb[i]) { 942 // Loop over pixels that achive neighbouring condition 943 Aux1=Neighb; 944 Aux1[i]=kFALSE; 945 for (int jj=0;jj<TRIGGER_PIXELS;jj++) 946 Aux2[jj]=kFALSE; 947 Aux2[j]=kTRUE; 948 // It checks if taking any of the pixels we lose 949 // neighbouring condition for trigger -1 950 for (iMulti=1;iMulti<(trigger_multi-1);iMulti++){ 951 if (!PassNextNeighbour(Aux1, &Aux2[0])) 952 break; 953 } 954 if (iMulti<(trigger_multi-1)){ 955 closed_pack=0; 956 break; 957 } 958 959 } 960 } 961 if (closed_pack){ 962 SlicesFirst[nFirst++] = iSli ; // We save time when it triggers 963 iReturn++ ; 964 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time) 965 break ; 966 } 967 else { 968 for (int k=0; k<TRIGGER_PIXELS; k++){ 969 if (Neighb[k]){ 970 Neighb[k]=kFALSE; 971 } 972 } 973 } 974 } 975 else 976 for (int k=0; k<TRIGGER_PIXELS; k++) 977 Neighb[k]=kFALSE; 978 } 979 } 980 break; 981 }; 982 default:{ 983 cout << "This topology is not implemented yet"<<endl; 984 break; 985 } 986 } 987 } 988 } // end of loop over the slices 989 } // end of conditional for a trigger Zero 990 991 // 992 // return the Number of FirstLevel Triggers 993 // 994 return iReturn ; 995 } 996 997 998 Bool_t MTrigger::PassNextNeighbour ( Bool_t m[], Bool_t *n) { 999 // 1000 // This function is looking for a next neighbour of pixels in n[] 1001 // above triggers using a NNlookup table. 1002 // This table is builded by the default constructor 1003 // 1004 1005 // 1006 // loop over all trigger pixels 1007 // 1008 1009 Bool_t return_val = kFALSE; 1010 1011 for ( Int_t i=0; i<TRIGGER_PIXELS; i++) { 1012 // 1013 // check if this pixel has a diskrminator signal 1014 // (this is inside n[] ) 1015 // 1016 1017 if ( n[i] && !return_val) { 1018 1019 // 1020 // look in the next neighbours from the lookuptable 1021 // 1022 1023 for ( Int_t kk=0; kk<6; kk++ ) { 1024 // 1025 // if the nextneighbour is outside the triggerarea do nothing 1026 // 1027 if (!return_val){ 1028 if (NN[i][kk] >= TRIGGER_PIXELS ) { 1029 1030 } 1031 // the nextneighbour is not inside the TRIGGER_PIXELS 1032 else { 1033 // 1034 // look if the boolean of nn pixels is true 1035 // 1036 1037 if ( m[ NN[i][kk] ] && !n[NN[i][kk]] ) { 1038 n[NN[i][kk]]=kTRUE ; 1039 return_val =kTRUE; 1040 } 1041 } 1042 } 1043 else break; 1044 } 1045 } 1046 } 1047 return(return_val); 1048 } -
trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx
r363 r373 1 #ifndef __MTrigger__ 2 #define __MTrigger__ 1 #ifndef __MTrigger__ 2 #define __MTrigger__ 3 4 #define CASE_SHOW 0 5 #define CASE_NSB 1 6 #define CASE_STAR 2 3 7 4 8 // class MTrigger … … 6 10 // implemented by Harald Kornmayer 7 11 // 8 // This is a class to simulate the trigger. 9 // It assumes a special response of the PMT for one single Photo-electron. 10 // 12 // This is a class to simulate the trigger. 13 // It assumes a special response of the PMT for one single Photo-electron. 14 // 11 15 // 12 16 // 13 17 #include <iostream.h> 14 #include <math.h> 18 #include <math.h> 15 19 16 20 #include "TROOT.h" … … 19 23 #include "TH1.h" 20 24 21 #include "Mdefine.h" 25 #include "Mdefine.h" 22 26 #include "MMcEvt.h" 23 27 24 28 #include "MTriggerDefine.h" 25 29 30 26 31 //========== 27 32 // MTrigger 28 33 // 29 // The simulation of the Trigger for MonteCarlo Events is using this 34 // The simulation of the Trigger for MonteCarlo Events is using this 30 35 // class. So all methods concerning the trigger should be done inside this 31 // class. 36 // class. 32 37 // 33 38 // For a better understanding of the behavior of the trigger is here small … … 37 42 // We now from the camera program (This is the surrounding of the class 38 43 // MTrigger.) that one photo electron leaves at time t the photo cathode 39 // of the pixel number iPix). 44 // of the pixel number iPix). 40 45 // 41 46 // At the end of the PMT, the preamp, the optical fiber transmission we 42 // get a signal of a given shape. After some discussion with Eckart the 43 // standard response function looks like this : 44 // 45 // It is a gaussian Signal with a given FWHM. 47 // get a signal of a given shape. After some discussion with Eckart the 48 // standard response function looks like this : 49 // 50 // It is a gaussian Signal with a given FWHM. 46 51 // 47 52 // So whenever a photo electron leaves the photo cathod, on has to add 48 // the standard response function to the analog signal of the pixel. 53 // the standard response function to the analog signal of the pixel. 49 54 // 50 // Each pixel of the camera has such an summed-up analog signal. It may 51 // look like this picture: 55 // Each pixel of the camera has such an summed-up analog signal. It may 56 // look like this picture: 52 57 // 53 58 // 54 59 // This is the input of the discriminator for the pixels. The output of 55 60 // the discriminator is a digital signal. The response of the diskriminator 56 // is not fixed at the moment. There are discussion about this topic. 61 // is not fixed at the moment. There are discussion about this topic. 57 62 // 58 63 // At the moment the response is very simple. Whenever the analog signal 59 // is crossing a defined threshold from below to above, a digital signal 60 // with a given length is created. 64 // is crossing a defined threshold from below to above, a digital signal 65 // with a given length is created. 61 66 // 62 // No wone can start with the simulation of different trigger levels.67 // No one can start with the simulation of different trigger levels. 63 68 // 64 69 // The TriggerLevelZero is a very easy one. It is just looking if there … … 66 71 // a TriggerLevelZero signal is created. 67 72 // 68 // The TriggerLevelOne is implemented now. This isbe a kind of next73 // The TriggerLevelOne is not implemented now. This will be a kind of next 69 74 // neighbour condition (i.e. four neigbouring analog signals at the same 70 75 // time, but this requests at least four digital signals at level ON, what 71 // is equivalent with a TriggerLevelZero. 76 // is equivalent with a TriggerLevelZero. 72 77 // 73 78 // … … 76 81 private: 77 82 // 78 // then for all pixels the shape of all the analog signals 83 // then for all pixels the shape of all the analog signals 79 84 // 80 85 Bool_t used [TRIGGER_PIXELS] ; // a boolean to indicated if the pixels is used in this event 81 Int_t nphot[TRIGGER_PIXELS]; // count the photo electrons per pixel (NSB phe are not counted) 86 Int_t nphotshow[TRIGGER_PIXELS]; // count the photo electrons per pixel coming from showers 87 Int_t nphotnsb[TRIGGER_PIXELS]; // count the photo electrons per pixel coming from NSB 88 Int_t nphotstar[TRIGGER_PIXELS]; // count the photo electrons per pixel coming from stars 82 89 83 90 Float_t *a_sig[TRIGGER_PIXELS] ; // the analog signal for pixels … … 96 103 Float_t sum_d_sig[TRIGGER_TIME_SLICES] ; 97 104 98 99 105 // 100 106 // first the data for the response function … … 103 109 Float_t ampl_resp ; // amplitude of the phe_response function (in mV) 104 110 Float_t sing_resp[ RESPONSE_SLICES ] ; // the shape of the phe_response function 111 Float_t peak_time ; // the time from the start of the response function to the maximum peak 105 112 106 113 TH1F *histPmt ; … … 112 119 // 113 120 114 Float_t chan_thres ; // the threshold (in mV) for each individuel pixels121 Float_t chan_thres[TRIGGER_PIXELS] ; // the threshold (in mV) for each individuel pixels 115 122 Float_t gate_leng ; // the length of the digital signal if analog signal is above threshold 116 123 117 124 Float_t trigger_multi ; // Number of Pixels requested for a Trigger 118 125 Int_t trigger_geometry ; // 0 means a pixel with trigger_multi-1 neighbours 126 // 1 means trigger_multi neighbours 127 // 2 means trigger_multi closed neighbours 119 128 // 120 129 // The lookup table for the next neighbours … … 128 137 129 138 Int_t nZero ; // how many ZeroLevel Trigger in one Event 130 Int_t SlicesZero[5] ; // Times Slices at which the ZeroLevel Triggers occur139 Bool_t SlicesZero[TRIGGER_TIME_SLICES] ; // Times Slices at which the ZeroLevel Triggers occur 131 140 132 141 Int_t nFirst ; // how many FirstLevel Trigger in one Event … … 136 145 Int_t SlicesSecond[5] ; // Times Slices at which the SecondLevel Triggers occur 137 146 147 private: 138 148 149 Float_t Fill( Int_t, Float_t, Int_t ) ; 150 151 Bool_t PassNextNeighbour( Bool_t m[], Bool_t *n) ; 152 139 153 public: 140 154 … … 145 159 void Reset() ; 146 160 147 Float_t Fill ( Int_t, Float_t ) ;161 Float_t FillShow( Int_t, Float_t ) ; 148 162 149 163 Float_t FillNSB( Int_t, Float_t ) ; 150 164 165 Float_t FillStar( Int_t, Float_t ) ; 166 151 167 void ElecNoise() ; 152 168 153 Int_t Diskriminate() ; 169 void SetResponseShape(); 170 171 void ReadParam(char name[]); 172 173 void Diskriminate() ; 174 175 void ShowSignal (MMcEvt *McEvt) ; 176 177 Int_t ZeroLevel() ; 154 178 155 179 Int_t FirstLevel() ; 156 157 Bool_t PassNextNeighbour( Bool_t m[] ) ;158 159 void ShowSignal (MMcEvt *McEvt) ;160 180 161 181 Float_t GetFirstLevelTime( Int_t il ) ; -
trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTriggerDefine.h
r372 r373 69 69 // channels with a diskrimiator signal at the same time 70 70 // 71 72 71 #define TRIGGER_GEOM 0 72 // 73 // This defines the geometry required for a trigger. There exists 74 // different meaning for this behaviour: 75 // 0 means a pixel with trigger_multi-1 neighbours 76 // 1 means trigger_multi neighbours 77 // 2 means trigger_multi closed neighbours 78 //
Note:
See TracChangeset
for help on using the changeset viewer.