Changeset 9462 for trunk/MagicSoft/Mars/msimcamera
- Timestamp:
- 06/20/09 10:14:33 (16 years ago)
- Location:
- trunk/MagicSoft/Mars/msimcamera
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/msimcamera/MSimAPD.cc
r9427 r9462 206 206 return kERROR; 207 207 } 208 208 /* 209 209 for (UInt_t idx=0; idx<npix; idx++) 210 210 { … … 212 212 static_cast<APD*>(fAPDs.UncheckedAt(idx))->FillRandom(freq, fStat->GetTimeFirst()); 213 213 } 214 */ 215 216 // This tries to initialize dead and relaxing cells properly. If 217 // the APD has not been initialized before the chip is randomsly 218 // filled, otherwise a time window of the default relaxing time 219 // is simulated, so that the previous influence is less than a permille. 220 for (UInt_t idx=0; idx<npix; idx++) 221 { 222 const Double_t freq = fRates ? (*fRates)[idx].GetPedestal() : fFreq; 223 static_cast<APD*>(fAPDs.UncheckedAt(idx))->Init(freq); 224 } 214 225 215 226 // Get number of photons … … 223 234 224 235 // Get arrival time of photon and idx 225 const Double_t t = ph.GetTime() ;236 const Double_t t = ph.GetTime()-fStat->GetTimeFirst(); 226 237 const Int_t idx = ph.GetTag(); 227 238 if (idx<0) … … 239 250 // Simulate hitting the APD (the signal height in effective 240 251 // "number of photons" is returned) 241 const Double_t hits = static_cast<APD*>(fAPDs.UncheckedAt(idx))->HitRandomCell (t);252 const Double_t hits = static_cast<APD*>(fAPDs.UncheckedAt(idx))->HitRandomCellRelative(t); 242 253 243 254 // FIXME: Make a proper simulation of the excess noise!!! … … 248 259 } 249 260 261 // Now we have to shift the evolved time of all APDs to the end of our 262 // simulated time. 263 for (UInt_t idx=0; idx<npix; idx++) 264 static_cast<APD*>(fAPDs.UncheckedAt(idx))->IncreaseTime(fStat->GetTimeLast()); 265 250 266 return kTRUE; 251 267 } -
trunk/MagicSoft/Mars/msimcamera/MSimTrigger.cc
r9318 r9462 42 42 // 43 43 // With a second look-up table fCoincidenceMap the analog channels are 44 // checked for coincidences. The coinciden se must at least be of the length44 // checked for coincidences. The coincidence must at least be of the length 45 45 // defined by fCoincidenceTime. The earliest coincide is then stored as 46 46 // trigger position. 47 // 48 // If a minimum multiplicity m is given, m signals above threshold 49 // in the coincidence patterns are enough to emit a trigger signal. 47 50 // 48 51 // … … 97 100 fEvtHeader(0), fElectronicNoise(0), fGain(0), 98 101 fDiscriminatorThreshold(-1), fDigitalSignalLength(8), fCoincidenceTime(0.5), 99 fShiftBaseline(kTRUE), fUngainSignal(kTRUE) 102 fShiftBaseline(kTRUE), fUngainSignal(kTRUE), fSimulateElectronics(kTRUE), 103 fMinMultiplicity(-1) 100 104 { 101 105 fName = name ? name : "MSimTrigger"; … … 107 111 // Take two TObjArrays with a collection of digital signals. 108 112 // Every signal from one array is compared with any from the other array. 109 // For all signals whi hc overlapsand which have an overlap time >gate113 // For all signals which overlap and which have an overlap time >gate 110 114 // a new digital signal is created storing start time and length of overlap. 111 115 // They are collected in a newly allocated TObjArray. A pointer to this array 112 116 // is returned. 113 117 // 114 // Th euser gains owenership of the object, ie.e., the user is responsible of118 // The user gains owenership of the object, i.e., the user is responsible of 115 119 // deleting the memory. 116 120 // 117 TObjArray *MSimTrigger::CalcCoincidence(const TObjArray &arr1, const TObjArray &arr2 , Float_t gate) const121 TObjArray *MSimTrigger::CalcCoincidence(const TObjArray &arr1, const TObjArray &arr2/*, Float_t gate*/) const 118 122 { 119 123 TObjArray *res = new TObjArray; … … 131 135 { 132 136 MDigitalSignal *ttl = new MDigitalSignal(*ttl1, *ttl2); 133 137 /* 134 138 if (ttl->GetLength()<=gate) 135 139 { … … 137 141 continue; 138 142 } 139 143 */ 140 144 res->Add(ttl); 141 145 } … … 143 147 144 148 res->SetOwner(); 149 150 return res; 151 } 152 153 class Edge : public TObject 154 { 155 private: 156 Double_t fEdge; 157 Int_t fRising; 158 159 public: 160 Edge(Double_t t, Int_t rising) : fEdge(t), fRising(rising) { } 161 Bool_t IsSortable() const { return kTRUE; } 162 Int_t Compare(const TObject *o) const { const Edge *e = static_cast<const Edge*>(o); if (e->fEdge<fEdge) return 1; if (e->fEdge>fEdge) return -1; return 0; } 163 164 Int_t IsRising() const { return fRising; } 165 Double_t GetEdge() const { return fEdge; } 166 }; 167 168 // -------------------------------------------------------------------------- 169 // 170 // Calculate a multiplicity trigger on the given array(s). The idx-array 171 // conatins all channels which should be checked for coincidences 172 // and the ttls array conatins the arrays with the digital signals. 173 // 174 // For the windows in which more or euqal than threshold channels have 175 // a high signal a new MDigitalSignal is created. newly allocated 176 // array with a collection of these trigger signals is returned. 177 // 178 TObjArray *MSimTrigger::CalcMinMultiplicity(const MArrayI &idx, const TObjArray &ttls, Int_t threshold) const 179 { 180 // Create a new array for the rising and falling edges of the signals 181 TObjArray times; 182 times.SetOwner(); 183 184 // Fill the array with edges from all digital signals of all our channels 185 for (UInt_t k=0; k<idx.GetSize(); k++) 186 { 187 TObjArray *arr = static_cast<TObjArray*>(ttls[idx[k]]); 188 189 TIter Next(arr); 190 MDigitalSignal *ttl = 0; 191 while ((ttl=static_cast<MDigitalSignal*>(Next()))) 192 { 193 times.Add(new Edge(ttl->GetStart(), 1)); 194 times.Add(new Edge(ttl->GetEnd(), -1)); 195 } 196 } 197 198 // Sort them in time 199 times.Sort(); 200 201 // Start with no channel active 202 Int_t lvl = 0; 203 204 TObjArray *res = new TObjArray; 205 res->SetOwner(); 206 207 // First remove all edges which do not change the status 208 // "below threshold" or "above threshold" 209 for (int i=0; i<times.GetEntriesFast(); i++) 210 { 211 // Get i-th edge 212 const Edge &e = *static_cast<Edge*>(times.UncheckedAt(i)); 213 214 // Claculate what the number of active channels after the edge is 215 const Int_t lvl1 = lvl + e.IsRising(); 216 217 // Remove edge if number of active channels before and after the 218 // edge lower is lower than the threshold or higher than 219 // the threshold 220 if (lvl+1<threshold || lvl-1>=threshold) 221 delete times.RemoveAt(i); 222 223 // keep the (now) "previous" level 224 lvl = lvl1<0 ? 0 : lvl1; 225 } 226 227 // Remove the empty slots from the array 228 times.Compress(); 229 230 // 231 for (int i=0; i<times.GetEntriesFast()-1; i++) 232 { 233 // get the current edge 234 const Edge &e0 = *static_cast<Edge*>(times.UncheckedAt(i)); 235 236 // go ahead if this is a falling edge 237 if (e0.IsRising()!=1) 238 continue; 239 240 // get the following edge (must be a falling edge now) 241 const Edge &e1 = *static_cast<Edge*>(times.UncheckedAt(i+1)); 242 243 // calculate the length of the digital signal 244 const Double_t len = e1.GetEdge()-e0.GetEdge(); 245 246 // Create a digital trigger signal 247 MDigitalSignal *ds = new MDigitalSignal(e0.GetEdge(), len); 248 //ds->SetIndex(lvl); 249 res->Add(ds); 250 } 145 251 146 252 return res; … … 231 337 } 232 338 233 if (fElectronicNoise && !fRouteAC.IsEmpty() && !fRouteAC.IsDefault ())339 if (fElectronicNoise && !fRouteAC.IsEmpty() && !fRouteAC.IsDefaultCol()) 234 340 { 235 341 // FIXME: Apply to analog channels when summing … … 238 344 } 239 345 240 if (fGain && !fRouteAC.IsEmpty() && !fRouteAC.IsDefault ())346 if (fGain && !fRouteAC.IsEmpty() && !fRouteAC.IsDefaultCol()) 241 347 { 242 348 // FIXME: Apply to analog channels when summing … … 255 361 *fLog << "Using " << fNameRouteAC << " for re-routing/summing of analog channels before discriminator." << endl; 256 362 257 if (fCoincidenceMap.IsEmpty() )363 if (fCoincidenceMap.IsEmpty() && fMinMultiplicity==0) 258 364 *fLog << "No coincidences of digital channels will be checked. Signal-above-threshold trigger applied." << endl; 259 365 else 260 *fLog << "Using " << fNameCoincidenceMap << " to check for coincidences of the digital channels." << endl; 366 { 367 *fLog << "Using "; 368 if (fCoincidenceMap.IsEmpty()) 369 *fLog << "the whole camera"; 370 else 371 *fLog << "patterns from " << fNameCoincidenceMap; 372 *fLog << " to check for "; 373 if (fMinMultiplicity==0) 374 *fLog << "coincidences of the digital channels." << endl; 375 else 376 *fLog << fMinMultiplicity << " multiplicity." << endl; 377 } 261 378 262 379 *fLog << "Using discriminator threshold of " << fDiscriminatorThreshold << endl; … … 265 382 } 266 383 384 /* 385 class MDigitalChannel : public TObjArray 386 { 387 private: 388 TObjArray fArray; 389 390 public: 391 MDigitalSignal *GetSignal(UInt_t i) { return static_cast<MDigitalSignal*>(fArray[i]); } 392 393 }; 394 */ 395 396 #include "MCamEvent.h" 397 class MTriggerSignal : public MParContainer, public MCamEvent 398 { 399 private: 400 TObjArray fSignals; 401 402 public: 403 MTriggerSignal() { fSignals.SetOwner(); } 404 405 void Add(MDigitalSignal *signal) { fSignals.Add(signal); } 406 407 MDigitalSignal *GetSignal(UInt_t i) { return static_cast<MDigitalSignal*>(fSignals[i]); } 408 409 void Sort() { fSignals.Sort(); } 410 411 Int_t GetNumSignals() const { return fSignals.GetEntriesFast(); } 412 413 Float_t GetFirstTrigger() const 414 { 415 MDigitalSignal *sig = static_cast<MDigitalSignal*>(fSignals[0]); 416 return sig ? sig->GetStart() : -1; 417 } 418 Bool_t GetPixelContent(Double_t&, Int_t, const MGeomCam&, Int_t) const 419 { 420 switch (1) 421 { 422 case 1: // yes/no 423 case 2: // first time 424 case 3: // length 425 case 4: // n 426 break; 427 } 428 429 return kTRUE; 430 } 431 void DrawPixelContent(Int_t) const 432 { 433 } 434 }; 435 436 437 void MSimTrigger::SetTrigger(Double_t pos) 438 { 439 // FIXME: Jitter! (Own class?) 440 fTrigger->SetVal(pos); 441 fTrigger->SetReadyToSave(); 442 443 // Trigger pattern to be set 444 // FIXME: Make flexible 445 const UInt_t pat = (UInt_t)~(MTriggerPattern::kTriggerLvl1 | (MTriggerPattern::kTriggerLvl1<<8)); 446 447 // Flag this event as triggered by the lvl1 trigger (FIXME?) 448 fEvtHeader->SetTriggerPattern(pos<0 ? 0 : pat); 449 fEvtHeader->SetReadyToSave(); 450 } 451 267 452 // -------------------------------------------------------------------------- 268 453 // … … 270 455 { 271 456 // Invalidate trigger 272 fTrigger->SetVal(-1); 457 //fTrigger->SetVal(-1); 458 // Calculate the minimum and maximum time for a valid trigger 459 const Double_t freq = fRunHeader->GetFreqSampling()/1000.; 460 const Float_t nsamp = fRunHeader->GetNumSamplesHiGain(); 461 const Float_t pulspos = fPulsePos->GetVal()/freq; 462 463 // Valid range in units of bins 464 const Float_t min = fCamera->GetValidRangeMin()+pulspos; 465 const Float_t max = fCamera->GetValidRangeMax()-(nsamp-pulspos); 466 467 if (!fSimulateElectronics) 468 { 469 SetTrigger(min); 470 return kTRUE; 471 } 273 472 274 473 // ================== Simulate channel bundling ==================== … … 297 496 { 298 497 const UInt_t idx = row[j]; 299 (*patches)[i].AddSignal((*fCamera)[idx]); 498 499 // FIXME: Shrinking the mapping table earlier (e.g. 500 // ReInit) would avoid a lot of if's 501 if (idx<fCamera->GetNumChannels()) 502 (*patches)[i].AddSignal((*fCamera)[idx]); 300 503 } 301 504 } … … 329 532 // omitted in the loop 330 533 if (fCoincidenceMap.IsEmpty()) 331 fCoincidenceMap.SetDefault(npatch); 332 333 // Calculate the minimum and maximum time for a valid trigger 334 const Double_t freq = fRunHeader->GetFreqSampling()/1000.; 335 const Float_t nsamp = fRunHeader->GetNumSamplesHiGain(); 336 const Float_t pulspos = fPulsePos->GetVal()/freq; 337 338 // Valid range in units of bins 339 const Float_t min = fCamera->GetValidRangeMin()+pulspos; 340 const Float_t max = fCamera->GetValidRangeMax()-(nsamp-pulspos); 534 { 535 if (fMinMultiplicity>0) 536 fCoincidenceMap.SetDefaultRow(npatch); 537 else 538 fCoincidenceMap.SetDefaultCol(npatch); 539 } 341 540 342 541 // Create an array for the individual triggers 343 TObjArray triggers; 344 triggers.SetOwner(); 542 MTriggerSignal triggers; 345 543 346 544 Int_t cnt = 0; … … 352 550 const MArrayI &idx = fCoincidenceMap.GetRow(j); 353 551 354 // Start with a copy of the first coincidence channel 355 TObjArray *arr = static_cast<TObjArray*>(ttls[idx[0]]->Clone()); 356 arr->SetOwner(); 357 358 // compare to all other channels in this coincidence patch, one by one 359 for (UInt_t k=1; k<idx.GetSize() && arr->GetEntriesFast()>0; k++) 360 { 361 TObjArray *res = CalcCoincidence(*arr, *static_cast<TObjArray*>(ttls[idx[k]]), 362 fCoincidenceTime); 363 364 // Delete the original array and keep the new one 365 delete arr; 366 arr = res; 367 } 552 TObjArray *arr = 0; 553 554 if (fMinMultiplicity>0) 555 { 556 arr = CalcMinMultiplicity(idx, ttls, fMinMultiplicity); 557 } 558 else 559 { 560 arr = CalcMinMultiplicity(idx, ttls, idx.GetSize()); 561 /* 562 // Start with a copy of the first coincidence channel 563 arr = static_cast<TObjArray*>(ttls[idx[0]]->Clone()); 564 arr->SetOwner(); 565 566 // compare to all other channels in this coincidence patch, one by one 567 for (UInt_t k=1; k<idx.GetSize() && arr->GetEntriesFast()>0; k++) 568 { 569 TObjArray *res = CalcCoincidence(*arr, *static_cast<TObjArray*>(ttls[idx[k]]));//, fCoincidenceTime); 570 571 // Delete the original array and keep the new one 572 delete arr; 573 arr = res; 574 }*/ 575 } 576 577 // Count the number of totally emitted coincidence signals 578 cnt += arr->GetEntriesFast(); 368 579 369 580 // Remove all signals which are not in the valid digitization range 370 581 // (This is not the digitization window, but the region in which 371 582 // the analog channels contain usefull data) 583 // and which are shorter than the defined coincidence gate. 372 584 TIter Next(arr); 373 585 MDigitalSignal *ttl = 0; 374 586 while ((ttl=static_cast<MDigitalSignal*>(Next()))) 375 587 { 588 if (ttl->GetLength()<fCoincidenceTime) 589 { 590 delete arr->Remove(ttl); 591 continue; 592 } 593 376 594 if (ttl->GetStart()<min) 377 595 { 378 596 delete arr->Remove(ttl); 379 597 rmlo++; 598 continue; 380 599 } 381 600 if (ttl->GetStart()>max) … … 383 602 delete arr->Remove(ttl); 384 603 rmhi++; 604 continue; 385 605 } 606 607 // Set trigger channel index 608 ttl->SetIndex(j); 386 609 } 387 610 … … 389 612 arr->Compress(); 390 613 391 cnt += arr->GetEntriesFast();392 393 614 // If we have at least one trigger keep the earliest one. 394 // FIXME: The triggers should be ordered in time automatically: To be checked! 615 // FIXME: The triggers might be ordered in time automatically: 616 // To be checked! 395 617 // FIXME: Simulate trigger dead-time! 396 618 if (arr->GetEntriesFast()>0) 397 triggers.Add( arr->RemoveAt(0));619 triggers.Add(static_cast<MDigitalSignal*>(arr->RemoveAt(0))); 398 620 399 621 // delete the allocated space 400 622 delete arr; 401 }402 403 // No trigger issued. Go on.404 if (triggers.GetEntriesFast()==0)405 {406 if (rmlo>0 || rmhi>0)407 *fLog << inf2 << rmlo << "/" << rmhi << " trigger out of valid range. No trigger raised." << endl;408 return kTRUE;409 623 } 410 624 … … 414 628 // is omitted 415 629 triggers.Sort(); 416 417 // FIXME: Jitter! (Own class?) 418 fTrigger->SetVal(static_cast<MDigitalSignal*>(triggers[0])->GetStart()); 419 fTrigger->SetReadyToSave(); 420 421 // Flag this event as triggered by the lvl1 trigger (FIXME?) 422 fEvtHeader->SetTriggerPattern((UInt_t)~(MTriggerPattern::kTriggerLvl1 | (MTriggerPattern::kTriggerLvl1<<8))); 423 fEvtHeader->SetReadyToSave(); 424 425 // inf2? 426 *fLog << inf; 427 *fLog << cnt << " triggers left in " << triggers.GetEntriesFast() << " patches (" << rmlo << "/" << rmhi << " trigger out of valid range), T=" << fTrigger->GetVal(); 630 // FIXME: Store triggers! (+ Reversed pixels?) 631 632 SetTrigger(triggers.GetFirstTrigger()); 633 634 // No trigger issued. Go on. 635 if (triggers.GetNumSignals()==0) 636 { 637 if (rmlo>0 || rmhi>0) 638 *fLog << inf2 << GetNumExecutions() << ": " << rmlo << "/" << rmhi << " trigger out of valid range. No trigger raised." << endl; 639 return kTRUE; 640 } 641 642 // Number of patches which have triggered out of the total number of 643 // Coincidence signals emitted. (If the total number is higher than 644 // the number of triggers either some triggers had to be removed or 645 // or a patch has emitted more than one trigger signal) 646 // FIXME: inf2? 647 *fLog << inf << GetNumExecutions() << ": "; 648 *fLog << setw(3) << triggers.GetNumSignals() << " triggers left out of "; 649 *fLog << setw(3) << cnt << " (" << rmlo << "/" << rmhi << " trigger out of valid range), T=" << fTrigger->GetVal(); 428 650 *fLog << endl; 651 652 //# Trigger characteristics: gate length (ns), min. overlapping time (ns), 653 //# amplitude and FWHM of (gaussian) single phe response for trigger: 654 //trigger_prop 3.0 0.25 1.0 2.0 429 655 430 656 return kTRUE; … … 438 664 // DigitalSignalLength: 8 439 665 // CoincidenceTime: 0.5 666 // SimulateElectronics: Yes 440 667 // 441 668 Int_t MSimTrigger::ReadEnv(const TEnv &env, TString prefix, Bool_t print) … … 472 699 } 473 700 701 if (IsEnvDefined(env, prefix, "SimulateElectronics", print)) 702 { 703 rc = kTRUE; 704 fSimulateElectronics = GetEnvValue(env, prefix, "SimulateElectronics", fSimulateElectronics); 705 } 706 707 if (IsEnvDefined(env, prefix, "MinMultiplicity", print)) 708 { 709 rc = kTRUE; 710 fMinMultiplicity = GetEnvValue(env, prefix, "MinMultiplicity", fMinMultiplicity); 711 } 712 474 713 return rc; 475 714 } -
trunk/MagicSoft/Mars/msimcamera/MSimTrigger.h
r9318 r9462 40 40 Bool_t fShiftBaseline; // Shift the baseline back to 0 for the threshold (needs ElectronicNoise [MPedestalCam]) 41 41 Bool_t fUngainSignal; // "Remove" the gain from the signal (needs Gain [MPedestalCam]) 42 Bool_t fSimulateElectronics; // If the electronics is not simulated the trigger is set artificially to the first photon arrived 43 44 Int_t fMinMultiplicity; // N out of M 42 45 43 46 // MSimTrigger 44 TObjArray *CalcCoincidence(const TObjArray &arr1, const TObjArray &arr2, Float_t gate=0) const; 47 TObjArray *CalcCoincidence(const TObjArray &arr1, const TObjArray &arr2/*, Float_t gate=0*/) const; 48 TObjArray *CalcMinMultiplicity(const MArrayI &idx, const TObjArray &ttls, Int_t threshold) const; 49 TObjArray *CalcCoincidences(const MArrayI &idx, const TObjArray &ttls) const; 50 void SetTrigger(Double_t pos); 45 51 46 52 // MTask
Note:
See TracChangeset
for help on using the changeset viewer.