Ignore:
Timestamp:
03/13/00 09:12:26 (25 years ago)
Author:
harald
Message:
This is the Version of MTrigger Class from the 10th of March 2000.
Some work was done by Oscar Blanch and Harald Kornmayer.
Location:
trunk/MagicSoft/Simulation/Detector/include-MTrigger
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx

    r372 r373  
    1414
    1515MTrigger::MTrigger() {
    16  
    17   FILE *unit_mtrig ;
    18   Int_t endflag = 1  ;
    19   char   datac[256] ;
    20   char   dummy[50] ;
     16  // ============================================================
    2117  //
    2218  //  default constructor
     
    2925  //     this parameters of the trigger may be changed
    3026  //  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 
    3235  //
    3336  //   allocate the memory for the 2dim arrays (a_sig, d_sig )
     
    4750  fwhm_resp = RESPONSE_FWHM       ;
    4851  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
    5460  //
    5561  //  check if the file MTrigger.card exists
     
    7076     
    7177      if (      strncmp (datac, "channel_threshold", 17 ) == 0 ) {
    72         sscanf (datac, "%s %f", dummy, &chan_thres ) ;
     78        sscanf (datac, "%s %f", dummy, &threshold ) ;
    7379      }
    7480      else if ( strncmp (datac, "gate_length", 11 ) == 0 ) {
     
    8086      else if ( strncmp (datac, "response_ampl", 13 ) == 0 ) {
    8187        sscanf (datac, "%s %f", dummy, &ampl_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 ) ;
    8294      }
    8395
     
    97109       << "[MTrigger]  Setting up the MTrigger with this values "<< endl ;
    98110  cout << endl
    99        << "[MTrigger]    ChannelThreshold:   " << chan_thres << " mV"
     111       << "[MTrigger]    ChannelThreshold:   " << threshold << " mV"
    100112       << endl ;
    101113
     
    106118  cout << "[MTrigger]    Response Amplitude: " << ampl_resp  << " mV"
    107119       << endl ;
     120  cout << "[MTrigger]    Trigger Multiplicity:      " << trigger_multi  << " pixels"
     121       << endl ;
     122  cout << "[MTrigger]    Trigger Topology: " << trigger_geometry
     123       << endl ;
    108124 
    109125  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
    110135  //
    111136  //    set up the response shape
     
    132157    //           << endl ;
    133158
    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 
    135179
    136180  //
     
    162206  GenElec = new TRandom() ;
    163207
    164 
    165208  //
    166209  //  Read in the lookup table for NN trigger
     
    169212  FILE *unit ;
    170213  int id ;
    171   float y ;
    172214
    173215  i = 0 ;
     
    201243  for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
    202244    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 ;
    205252  }
    206253
     
    209256  }
    210257 
     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
     275MTrigger::~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 
     289void 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
    211309  //
    212310  //   set the information about the Different Level Triggers to zero
     
    220318    SlicesSecond[i] = 0 ;
    221319  }
    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
     323Float_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
     343Float_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
     363Float_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
     383Float_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   
    303433    if ( used[iPix] == FALSE ) {
    304434      used [iPix] = TRUE ;
    305435      //      baseline[iPix] = 0. ;
    306 
     436     
    307437      for (i=0; i < TRIGGER_TIME_SLICES; i++ ) {
    308438        a_sig[iPix][i] = 0. ;
     
    312442   
    313443    //
    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      }
    321464    }
    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
    426485
    427486void MTrigger::ElecNoise() {
    428 
     487  // ============================================================
     488  //
     489  //    adds the noise due to optronic and electronic
     490  //    to the signal
     491  //
    429492  Float_t rausch ;
    430493
     
    442505    }
    443506  }
    444 
    445 }
    446 
    447 
    448 Int_t MTrigger::Diskriminate() {
    449 
    450   //  cout << " MTrigger::Diskriminate()" << flush ;
    451 
     507}
     508
     509void 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 
    452520  Int_t  iM = 0 ;
    453521  Int_t  i, ii  ;
    454522
     523
    455524  Int_t  jmax = (Int_t) (gate_leng * SLICES_PER_NSEC )  ;
    456 
    457525
    458526  //
     
    461529  //
    462530
    463 
    464531  for ( i=0 ; i < TRIGGER_PIXELS ; i++ ) {
    465532    if ( used[i] == TRUE ) {
     
    472539      baseline[i] = baseline[i] / ( (Float_t ) TRIGGER_TIME_SLICES)  ;
    473540
    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      //
    478546      for ( ii = 0 ;  ii < TRIGGER_TIME_SLICES ; ii++ ) {
    479547        a_sig[i][ii] = a_sig[i][ii] - baseline[i] ;
     
    482550  }
    483551 
     552  // 
     553  //  now the diskrimination is coming
    484554  //
    485555  //  take only that pixel which are used
     
    488558  for ( i=0 ; i < TRIGGER_PIXELS; i++  ) {
    489559    if ( used [i] == TRUE ) {
    490       //cout << "Pixel " << i << " used"  ;
    491        
     560           
    492561      for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
    493      
    494562        //
    495563        // first check if the signal is crossing the CHANNEL_THRESHOLD
     
    497565        //
    498566       
    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]  ) {
    501569          {
    502570            if ( dknt[i] == FALSE ) {
     
    513581              if ( ii+j  < TRIGGER_TIME_SLICES ) {
    514582                d_sig  [i][ii+j] = 1. ; 
    515                 sum_d_sig [ii+j] += 1. ; 
    516583              }
    517584            }
     
    519586          }
    520587        }
    521       }
    522       //      cout << endl ;
     588        else d_sig[i][ii]=0.;
     589      }
    523590    }
    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}
    696593
    697594
    698595void MTrigger::ShowSignal (MMcEvt *McEvt) {
     596  // ============================================================
    699597  //
    700598  //  This method is used to book the histogramm to show the signal in
     
    790688}
    791689 
     690
     691Int_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
     756Int_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
     998Bool_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
    37
    48//     class MTrigger
     
    610//     implemented by Harald Kornmayer
    711//
    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//
    1115//
    1216//
    1317#include <iostream.h>
    14 #include <math.h> 
     18#include <math.h>
    1519
    1620#include "TROOT.h"
     
    1923#include "TH1.h"
    2024
    21 #include "Mdefine.h" 
     25#include "Mdefine.h"
    2226#include "MMcEvt.h"
    2327
    2428#include "MTriggerDefine.h"
    2529
     30
    2631//==========
    2732//  MTrigger
    2833//
    29 //  The simulation of the Trigger for MonteCarlo Events is using this 
     34//  The simulation of the Trigger for MonteCarlo Events is using this
    3035//  class. So all methods concerning the trigger should be done inside this
    31 //  class. 
     36//  class.
    3237//
    3338//  For a better understanding of the behavior of the trigger is here small
     
    3742//  We now from the camera program (This is the surrounding of the class
    3843//  MTrigger.) that one photo electron leaves at time t the photo cathode
    39 //  of the pixel number iPix). 
     44//  of the pixel number iPix).
    4045//
    4146//  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.
    4651//
    4752//  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.
    4954//
    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:
    5257//
    5358//
    5459//  This is the input of the discriminator for the pixels. The output of
    5560//  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.
    5762// 
    5863//  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.
    6166//
    62 //  Now one can start with the simulation of different trigger levels.
     67//  No one can start with the simulation of different trigger levels.
    6368// 
    6469//  The TriggerLevelZero is a very easy one. It is just looking if there
     
    6671//  a TriggerLevelZero signal is created.
    6772//
    68 //  The TriggerLevelOne is implemented now. This is be a kind of next
     73//  The TriggerLevelOne is not implemented now. This will be a kind of next
    6974//  neighbour condition (i.e. four neigbouring analog signals at the same
    7075//  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.
    7277// 
    7378// 
     
    7681 private:
    7782  //
    78   //    then for all pixels the shape of all the analog signals 
     83  //    then for all pixels the shape of all the analog signals
    7984  //
    8085  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
    8289 
    8390  Float_t  *a_sig[TRIGGER_PIXELS] ; //  the analog signal for pixels
     
    96103  Float_t sum_d_sig[TRIGGER_TIME_SLICES] ;
    97104
    98 
    99105  //
    100106  //    first the data for the response function
     
    103109  Float_t ampl_resp ;                      // amplitude of the phe_response function (in mV)
    104110  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
    105112
    106113  TH1F     *histPmt ;
     
    112119  //
    113120 
    114   Float_t chan_thres ; // the threshold (in mV) for each individuel pixels
     121  Float_t chan_thres[TRIGGER_PIXELS] ; // the threshold (in mV) for each individuel pixels
    115122  Float_t gate_leng  ; // the length of the digital signal if analog signal is above threshold
    116123
    117124  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
    119128  //
    120129  //  The lookup table for the next neighbours
     
    128137
    129138  Int_t  nZero ;         // how many ZeroLevel Trigger in one Event
    130   Int_t  SlicesZero[5] ; // Times Slices at which the ZeroLevel Triggers occur
     139  Bool_t  SlicesZero[TRIGGER_TIME_SLICES] ; // Times Slices at which the ZeroLevel Triggers occur
    131140
    132141  Int_t  nFirst ;         // how many FirstLevel Trigger in one Event
     
    136145  Int_t  SlicesSecond[5] ; // Times Slices at which the SecondLevel Triggers occur
    137146
     147private:
    138148
     149  Float_t  Fill( Int_t, Float_t, Int_t ) ; 
     150
     151  Bool_t PassNextNeighbour( Bool_t m[], Bool_t *n) ;
     152 
    139153public:
    140154
     
    145159  void Reset() ;
    146160
    147   Float_t  Fill( Int_t, Float_t ) ; 
     161  Float_t  FillShow( Int_t, Float_t ) ; 
    148162
    149163  Float_t  FillNSB( Int_t, Float_t ) ; 
    150164
     165  Float_t  FillStar( Int_t, Float_t ) ; 
     166
    151167  void ElecNoise() ;
    152168
    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() ;
    154178
    155179  Int_t FirstLevel() ;   
    156 
    157   Bool_t PassNextNeighbour( Bool_t m[] ) ;
    158  
    159   void ShowSignal (MMcEvt *McEvt) ;
    160180
    161181  Float_t GetFirstLevelTime( Int_t il ) ;
  • trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTriggerDefine.h

    r372 r373  
    6969//       channels with a diskrimiator signal at the same time
    7070//
    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.