Ignore:
Timestamp:
02/08/00 12:50:36 (25 years ago)
Author:
harald
Message:
This is the version of the class MTrigger that was presented at the
general MAGIC in BARCELONA at the beginning of February. It is inside the
repository for further development. Especially for a better implementation
of diskriminator, NN, secondLevelTrigger, and NSB simulations.
Location:
trunk/MagicSoft/Simulation/Detector/include-MTrigger
Files:
2 edited

Legend:

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

    r307 r351  
    66#include "MTrigger.hxx"
    77
     8#include "TROOT.h"
     9#include "TFile.h"
     10#include "TH1.h"
     11#include "TObjArray.h"
     12#include "MGTriggerSignal.hxx"
     13
     14
     15MTrigger::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, &ampl_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
     226MTrigger::~MTrigger() {
     227
     228  delete histPmt ;
     229}
     230 
     231void 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
     263Float_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
     350Float_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
     426void 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
     447Int_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
     561Int_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
     635Bool_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
     688Float_t MTrigger::GetFirstLevelTime(Int_t il ) {
     689  return ( (Float_t)SlicesFirst[il]/ SLICES_PER_NSEC   ) ;
     690}
     691
     692
     693
     694void 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
    24//     class MTrigger
    35//
     
    1214#include <math.h>
    1315
     16#include "TROOT.h"
    1417#include "TObject.h"
     18#include "TRandom.h"
     19#include "TH1.h"
    1520
    1621#include "Mdefine.h"
     22#include "MMcEvt.h"
    1723
    18 #define TRIGGER_TIME_SLICES    400
     24#include "MTriggerDefine.h"
     25
     26
     27//==========
     28//  MTrigger
    1929//
    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.
    2233//
    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.
    2436//
    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:
    2853//
    2954//
    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.
    3368//
    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// 
     75class MTrigger {
    3876
    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
    5485
     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
     140public:
     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.