//___________________________________________________________________________________________ void KVIDTelescope::Print(Option_t* opt) const { // print out telescope structure //if opt="fired" only fired detectors are printed TIter next(fDetectors); KVDetector* obj; if (!strcmp(opt, "fired")) { while ((obj = (KVDetector*) next())) { if (obj->Fired() || obj->GetEnergy()) obj->Print("data"); } } else { cout << "\n" << opt << "Structure of KVIDTelescope object: " << GetName() << " " << GetType() << endl; cout << opt << "--------------------------------------------------------" << endl; while ((obj = (KVDetector*) next())) { cout << opt << "Detector: " << obj->GetName() << endl; } } }
Bool_t KVReconstructedEvent::AnalyseDetectors(TList * kvtl) { // Loop over detectors in list // if any detector has fired, start construction of new detected particle // More precisely: If detector has fired, // making sure fired detector hasn't already been used to reconstruct // a particle, then we create and fill a new detected particle. // In order to avoid creating spurious particles when reading data, // by default we ask that ALL coder values be non-zero here i.e. data and time-marker. // This can be changed by calling SetPartSeedCond("any"): in this case, // particles will be reconstructed starting from detectors with at least 1 fired parameter. KVDetector *d; TIter next(kvtl); while( (d = (KVDetector*)next()) ){ /* If detector has fired, making sure fired detector hasn't already been used to reconstruct a particle, then we create and fill a new detected particle. */ if ( (d->Fired( fPartSeedCond.Data() ) && !d->IsAnalysed()) ) { KVReconstructedNucleus *kvdp = AddParticle(); //add all active detector layers in front of this one //to the detected particle's list kvdp->Reconstruct(d); //set detector state so it will not be used again d->SetAnalysed(kTRUE); } } return kTRUE; }
void KVIDTelescope::CalculateParticleEnergy(KVReconstructedNucleus* nuc) { // The energy of each particle is calculated as follows: // // E = dE_1 + dE_2 + ... + dE_N // // dE_1, dE_2, ... = energy losses measured in each detector through which // the particle has passed (or stopped, in the case of dE_N). // These energy losses are corrected for (Z,A)-dependent effects // such as pulse-heigth defect in silicon detectors, losses in // windows of gas detectors, etc. // // Whenever possible, the energy loss for fired detectors which are uncalibrated // or not functioning is calculated. In this case the status returned by GetCalibStatus() // will be KVIDTelescope::kCalibStatus_Calculated. // If none of the detectors is calibrated, the particle's energy cannot be calculated & // the status will be KVIDTelescope::kCalibStatus_NoCalibrations. // Otherwise, the status code will be KVIDTelescope::kCalibStatus_OK. //status code fCalibStatus = kCalibStatus_NoCalibrations; UInt_t z = nuc->GetZ(); //uncharged particles if (z == 0) return; KVDetector* d1 = GetDetector(1); KVDetector* d2 = (fDetectors->GetSize() > 1 ? GetDetector(2) : 0); Bool_t d1_cal = d1->IsCalibrated(); Bool_t d2_cal = (d2 ? d2->IsCalibrated() : kFALSE); //no calibrations if (!d1_cal && !d2) return; if ((d1 && d2) && !d1_cal && !d2_cal) return; //status code fCalibStatus = kCalibStatus_OK; UInt_t a = nuc->GetA(); // particles stopped in first member of telescope if (nuc->GetStatus() == 3) { if (d1_cal) { nuc->SetEnergy(d1->GetCorrectedEnergy(nuc, -1, kFALSE)); //N.B.: transmission=kFALSE because particle stop in d1 } return; } Double_t e1, e2, einc; e1 = e2 = einc = 0.0; if (!d1_cal) {//1st detector not calibrated - calculate from residual energy in 2nd detector //second detector must exist and have all acquisition parameters fired with above-pedestal value if (d2 && d2->Fired("Pall")) e2 = d2->GetCorrectedEnergy(nuc, -1, kFALSE); //N.B.: transmission=kFALSE because particle stop in d2 if (e2 <= 0.0) { // zero energy loss in 2nd detector ? can't do anything... fCalibStatus = kCalibStatus_NoCalibrations; return; } //calculate & set energy loss in dE detector //N.B. using e2 for the residual energy after detector 1 means //that we are assuming the particle stops in detector 2. //if this is not true, we will underestimate the energy of the particle. e1 = d1->GetDeltaEFromERes(z, a, e2); if (e1 < 0.0) e1 = 0.0; else { d1->SetEnergyLoss(e1); d1->SetEResAfterDetector(e2); e1 = d1->GetCorrectedEnergy(nuc); //status code fCalibStatus = kCalibStatus_Calculated; } } else {//1st detector is calibrated too: get corrected energy loss e1 = d1->GetCorrectedEnergy(nuc); } if (d2 && !d2_cal) {//2nd detector not calibrated - calculate from energy loss in 1st detector e1 = d1->GetCorrectedEnergy(nuc); if (e1 <= 0.0) { // zero energy loss in 1st detector ? can't do anything... fCalibStatus = kCalibStatus_NoCalibrations; return; } //calculate & set energy loss in 2nd detector e2 = d1->GetEResFromDeltaE(z, a); if (e2 < 0.0) e2 = 0.0; else { e2 = d2->GetDeltaE(z, a, e2); d2->SetEnergyLoss(e2); e2 = d2->GetCorrectedEnergy(nuc); //status code fCalibStatus = kCalibStatus_Calculated; } } else if (d2) { //2nd detector is calibrated too: get corrected energy loss e2 = d2->GetCorrectedEnergy(nuc, -1, kFALSE);//N.B.: transmission=kFALSE because particle assumed to stop in d2 // recalculate corrected energy in first stage using info on Eres d1->SetEResAfterDetector(e2); e1 = d1->GetCorrectedEnergy(nuc); } //incident energy of particle (before 1st member of telescope) einc = e1 + e2; Double_t coherence_tolerance = gEnv->GetValue("KVIDTelescope.CoherencyTolerance", 1.05); if (coherence_tolerance < 1) coherence_tolerance += 1.00; //Now we have to work our way up the list of detectors from which the particle was //reconstructed. For each fired & calibrated detector which is only associated with //one particle in the events, we add the corrected measured energy loss //to the particle. For uncalibrated, unfired detectors and detectors through which //more than one particle has passed, we calculate the corrected energy loss and add it //to the particle. int ndets = nuc->GetNumDet(); if (ndets > (int)GetSize()) { //particle passed through other detectors before this idtelesocpe //look at detectors not in this id telescope int idet = GetSize();//next detector after delta-e member of IDTelescope (stopping detector = 0) while (idet < ndets) { KVDetector* det = nuc->GetDetector(idet); if (det->Fired() && det->IsCalibrated() && det->GetNHits() == 1) { Double_t dE = det->GetEnergy(); //in order to check if particle was really the only one to //hit each detector, we calculate the particle's energy loss //from its residual energy. if the measured energy loss is //significantly larger, there may be a second particle. e1 = det->GetDeltaEFromERes(z, a, einc); if (e1 < 0.0) e1 = 0.0; det->SetEResAfterDetector(einc); dE = det->GetCorrectedEnergy(nuc); einc += dE; } else { // Uncalibrated/unfired/multihit detector. Calculate energy loss. //calculate energy of particle before detector from energy after detector e1 = det->GetDeltaEFromERes(z, a, einc); if (e1 < 0.0) e1 = 0.0; if (det->GetNHits() > 1) { //Info("CalculateParticleEnergy", // "Detector %s was hit by %d particles. Calculated energy loss for particle %f MeV", // det->GetName(), det->GetNHits(), e1); if (!(det->Fired() && det->IsCalibrated())) { det->SetEnergyLoss(e1 + det->GetEnergy());// sum up calculated energy losses in uncalibrated detector } //status code fCalibStatus = kCalibStatus_Multihit; } else if (!det->Fired() || !det->IsCalibrated()) { //Info("CalculateParticleEnergy", // "Detector %s uncalibrated/not fired. Calculated energy loss for particle %f MeV", // det->GetName(), e1); det->SetEnergyLoss(e1); //status code fCalibStatus = kCalibStatus_Calculated; } det->SetEResAfterDetector(einc); e1 = det->GetCorrectedEnergy(nuc, e1); einc += e1; } idet++; } } //einc is now the energy of the particle before crossing the first detector nuc->SetEnergy(einc); }