void KVFAZIA::Build(Int_t) { // Build the combined INDRA & FAZIA arrays GetGeometryParameters(); GenerateCorrespondanceFile(); if (!gGeoManager) { new TGeoManager("FAZIA", Form("FAZIA geometry for dataset %s", gDataSet->GetName())); TGeoMaterial* matVacuum = gGeoManager->GetMaterial("Vacuum"); if (!matVacuum) { matVacuum = new TGeoMaterial("Vacuum", 0, 0, 0); matVacuum->SetTitle("Vacuum"); } TGeoMedium* Vacuum = gGeoManager->GetMedium("Vacuum"); if (!Vacuum) Vacuum = new TGeoMedium("Vacuum", 1, matVacuum); TGeoVolume* top = gGeoManager->MakeBox("WORLD", Vacuum, 500, 500, 500); gGeoManager->SetTopVolume(top); } BuildFAZIA(); if (fBuildTarget) BuildTarget(); KVGeoImport imp(gGeoManager, KVMaterial::GetRangeTable(), this, kTRUE); imp.SetDetectorPlugin(ClassName()); imp.SetNameCorrespondanceList(fCorrespondanceFile.Data()); // any additional structure name formatting definitions DefineStructureFormats(imp); // the following parameters are optimized for a 12-block compact // geometry placed at 80cm with rings 1-5 of INDRA removed. // make sure that the expected number of detectors get imported! imp.ImportGeometry(fImport_dTheta, fImport_dPhi, fImport_ThetaMin, fImport_PhiMin, fImport_ThetaMax, fImport_PhiMax); /* KVFAZIADetector* det=0; TIter next_d(GetDetectors()); while ( det = (KVFAZIADetector* )next_d() ){ printf("%s %s %d %d %d\n",det->GetName(),det->GetFAZIAType(),det->GetBlockNumber(),det->GetQuartetNumber(),det->GetTelescopeNumber()); } */ SetIdentifications(); SortIDTelescopes(); KVDetector* det = GetDetector("SI2-T1-Q1-B001"); det->GetIDTelescopes()->ls(); SetDetectorThicknesses(); SetBit(kIsBuilt); }
//___________________________________________________________________________ Double_t KVChannelVolt::Compute(Double_t chan) const { Double_t gain = 1.; KVDetector* det = GetDetector(); if (det) gain = det->GetGain(); //Calculate the calibrated signal strength in volts for a given channel number. if (fReady) { return (fPar[0] + fPar[1] * chan + fPar[2] * chan * chan) * gain_ref / gain; } else { return 0.; } }
TList* KVGroup::GetDetectorsInLayer(UInt_t lay) { // lay=1 : create and fill list with detectors closest to target // lay=GetNumberOfDetectorLayers() : detectors furthest from target TList* dets = new TList; TIter next(GetDetectors()); KVDetector* d; while ((d = (KVDetector*)next())) { if (lay == (UInt_t)d->GetAlignedDetectors()->GetEntries()) dets->Add(d); } return dets; }
UInt_t KVGroup::GetNumberOfDetectorLayers() { // The number of detector layers is the maximum number of detectors in the // group which are placed one in front of the other, i.e. we interrogate // each detector as to how many detectors there are in front of it UInt_t max = 0; TIter next(GetDetectors()); KVDetector* d; while ((d = (KVDetector*)next())) { UInt_t e = d->GetAlignedDetectors()->GetEntries(); if (e > max) max = e; } return max; }
Bool_t KVIDTelescope::CheckTheoreticalIdentificationThreshold(KVNucleus* ION, Double_t EINC) { // Return kTRUE if energy of ION is > minimum incident energy required for identification // This theoretical limit is defined here to be the incident energy for which the // dE in the first detector of a dE-E telescope is maximum. // If EINC>0 it is assumed to be the energy of the ion just before the first detector // (case where ion would have to pass other detectors before reaching this telescope). // // If this is not a dE-E telescope, we return kTRUE by default. if (GetSize() < 2) return kTRUE; KVDetector* dEdet = GetDetector(1); Double_t emin = dEdet->GetEIncOfMaxDeltaE(ION->GetZ(), ION->GetA()); if (EINC > 0.0) return (EINC > emin); return (ION->GetEnergy() > emin); }
const Char_t* KVINDRATelescope::GetArrayName() { // Name of telescope given in the form Det1_Det2_..._Ring-numberTelescope-number // where Det1 etc. are the ACTIVE detector layers of the telescope // The detectors are signified by their TYPE names i.e. KVDetector::GetType TIter next_det(GetDetectors()); KVDetector* kdet; TString dummy; while ((kdet = (KVDetector*) next_det())) { //loop over detectors in telescope if (dummy == "") dummy = kdet->GetType(); else dummy += kdet->GetType(); dummy += "_"; } fName.Form("%s%02d%02d", dummy.Data(), GetRingNumber(), GetNumber()); return fName.Data(); }
void KVINDRAUpDater::SetChVoltParameters(KVDBRun* kvrun) { KVRList* param_list = kvrun->GetLinks("Channel-Volt"); if (!param_list) return; if (!param_list->GetSize()) return; KVDetector* kvd; KVDBParameterSet* kvps; KVCalibrator* kvc; TIter next_ps(param_list); TString str; // Setting Channel-Volts calibration parameters while ((kvps = (KVDBParameterSet*) next_ps())) { // boucle sur les parametres str = kvps->GetName(); str.Remove(str.Sizeof() - 4, 3); //Removing 3 last letters (ex : "_PG") kvd = fArray->GetDetector(str.Data()); if (!kvd) Warning("SetChVoltParameters(UInt_t)", "Dectector %s not found !", str.Data()); else { // detector found kvc = kvd->GetCalibrator(kvps->GetName(), kvps->GetTitle()); if (!kvc) Warning("SetChVoltParameters(UInt_t)", "Calibrator %s %s not found !", kvps->GetName(), kvps->GetTitle()); else { //calibrator found for (Int_t i = 0; i < kvc->GetNumberParams(); i++) { kvc->SetParameter(i, kvps->GetParameter(i)); } kvc->SetStatus(kTRUE); // calibrator ready } //calibrator found } //detector found } //boucle sur les parameters }
//_________________________________________________________________________________________ void KVINDRA::FillListsOfDetectorsByType() { //Fill lists of ChIo, Si, CsI and phoswich fChIo->Clear(); fSi->Clear(); fCsI->Clear(); fPhoswich->Clear(); TIter next_det(GetDetectors()); KVDetector* kvd; while ((kvd = (KVDetector*) next_det())) { kvd->SetNameOfArray("INDRA"); if (kvd->InheritsFrom("KVChIo")) { fChIo->Add(kvd); } if (kvd->InheritsFrom("KVSilicon")) { fSi->Add(kvd); } if (kvd->InheritsFrom("KVCsI")) { fCsI->Add(kvd); } if (kvd->InheritsFrom("KVPhoswich")) { fPhoswich->Add(kvd); } } }
void KVINDRAUpDater::SetVoltEnergyChIoSiParameters(KVDBRun* kvrun) { KVRList* param_list = kvrun->GetLinks("Volt-Energy ChIo-Si"); if (!param_list) return; if (!param_list->GetSize()) { return; } KVDetector* kvd; KVDBParameterSet* kvps; KVCalibrator* kvc; TIter next_ps(param_list); // Setting Channel-Volts calibration parameters while ((kvps = (KVDBParameterSet*) next_ps())) { // boucle sur les parametres kvd = fArray->GetDetector(kvps->GetName()); if (!kvd) { /* Warning("SetVoltEnergyParameters(UInt_t)", "Dectector %s not found !", kvps->GetName()); */ } else { // detector found kvc = kvd->GetCalibrator(kvps->GetName(), kvps->GetTitle()); if (!kvc) Warning("SetVoltEnergyParameters(UInt_t)", "Calibrator %s %s not found !", kvps->GetName(), kvps->GetTitle()); else { //calibrator found for (Int_t i = 0; i < kvc->GetNumberParams(); i++) { kvc->SetParameter(i, kvps->GetParameter(i)); } kvc->SetStatus(kTRUE); // calibrator ready } //calibrator found } //detector found } //boucle sur les parameters }
void KVINDRAUpDater_e475s::SetCalibrationParameters(UInt_t run){ //Set calibration parameters for this run. //This will: // remove all the calibrators of all the detectors ready to receive the calibrators for the run (handled by child classes), // set calibration parameters for the run // set pedestals for the run cout << "Setting calibration parameters of INDRA array for run " << run << ":" << endl; KVDBRun *kvrun = gIndraDB->GetRun(run); if (!kvrun) { Error("SetParameters(UInt_t)", "Run %u not found in database!", run); return; } //Reset all calibrators of all detectors first TIter next(gIndra->GetListOfDetectors()); KVDetector *kvd; while ((kvd = (KVDetector *) next())) { if (kvd->InheritsFrom("KVSiLi") || kvd->InheritsFrom("KVSi75")){ if (kvd->GetListOfCalibrators()) kvd->RemoveCalibrators(); kvd->SetCalibrators(); } else { if (kvd->GetListOfCalibrators()) { kvd->RemoveCalibrators(); TIter lacq(kvd->GetACQParamList()); KVACQParam* acq = 0; while ( (acq = (KVACQParam* )lacq()) ){ acq->SetPedestal(0); } } } } SetCalibParameters(kvrun); SetPedestals(kvrun); }
void KVElasticCountRates::FillHistograms(KVNameValueList* dets) { // parse the list dets // fill histograms with energy loss for all detectors // clear the detector energy losses // delete the list if (!dets) return; Int_t ndets = dets->GetNpar(); for (int i = 0; i < ndets; i++) { TString detname = dets->GetNameAt(i); KVDetector* det = gMultiDetArray->GetDetector(detname); if (!det) continue; TH1F* histo = (TH1F*)fHistos.FindObject(detname); if (!histo) { histo = new TH1F(detname, Form("Eloss in %s", detname.Data()), fBinE, 0, 0); fHistos.Add(histo); } double de = dets->GetDoubleValue(i); histo->Fill(de, xsec * sin(theta * TMath::DegToRad())); histo = (TH1F*)fHistos.FindObject(detname + "_dW"); if (!histo) { histo = new TH1F(detname + "_dW", Form("Solid angle of %s", detname.Data()), fBinE, 0, 0); fHistos.Add(histo); } histo->Fill(de, sin(theta * TMath::DegToRad())); TH2F* histo2 = (TH2F*)fHistos.FindObject(detname + "_map"); if (!histo2) { histo2 = new TH2F(detname + "_map", Form("Map of %s", detname.Data()), 100, 0, 0, 100, 0, 0); fHistos.Add(histo2); } histo2->Fill(theta, phi, xsec); det->Clear(); } delete dets; }
void KVFAZIA::GetDetectorEvent(KVDetectorEvent* detev, TSeqCollection* signals) { // First step in event reconstruction based on current status of detectors in array. // Fills the given KVDetectorEvent with the list of all groups which have fired. // i.e. loop over all groups of the array and test whether KVGroup::Fired() returns true or false. // // If the list of fired acquisition parameters 'signals' is given, KVMultiDetArray::GetDetectorEvent // is called // if (signals) { // list of fired acquisition parameters given TIter next_par(signals); KVSignal* par = 0; KVDetector* det = 0; KVGroup* grp = 0; while ((par = (KVSignal*)next_par())) { if (!(par->GetN() > 0)) Info("GetDetectorEvent", "%s empty", par->GetName()); par->DeduceFromName(); if ((det = GetDetector(par->GetDetectorName()))) { ((KVFAZIADetector*)det)->SetSignal(par, par->GetType()); if ((!(((KVFAZIADetector*)det)->GetSignal(par->GetType())->GetN() > 0))) Warning("Error", "%s %s empty signal is returned", det->GetName(), par->GetType()); if ((grp = det->GetGroup()) && !detev->GetGroups()->FindObject(grp)) { detev->AddGroup(grp); } } else { Error("GetDetectedEvent", "Unknown detector %s !!!", par->GetDetectorName()); } } } else { KVMultiDetArray::GetDetectorEvent(detev, 0); } }
//___________________________________________________________________________ Double_t KVChannelVolt::Invert(Double_t volts) { //Given the calibrated (or simulated) signal amplitude in volts, //calculate the corresponding channel number according to the //calibration parameters (useful for filtering simulations). Double_t gain = 1.; KVDetector* det = GetDetector(); if (det) gain = det->GetGain(); Int_t channel = 0; if (fReady) { if (fPar[2]) { // quadratic transfer function Double_t c; c = fPar[1] * fPar[1] - 4. * fPar[2] * (fPar[0] - gain / gain_ref * volts); if (c < 0.0) return -1; c = (-fPar[1] + TMath::Sqrt(c)) / (2.0 * fPar[2]); if (c < 0.0 && ((-fPar[1] - TMath::Sqrt(c)) / (2.0 * fPar[2])) > 0.0) { c = (-fPar[1] - TMath::Sqrt(c)) / (2.0 * fPar[2]); } channel = (Int_t)(c + 0.5); } else { // linear transfer function channel = (Int_t)(0.5 + (gain / gain_ref * volts - fPar[0]) / fPar[1]); } } else { Warning("Compute", "Parameters not correctly initialized"); } return (Double_t) channel; }
void KVGeoImport::ParticleEntersNewVolume(KVNucleus *) { // All detectors crossed by the particle's trajectory are added to the multidetector // and the groups (KVGroup) of aligned detectors are set up KVDetector* detector = GetCurrentDetector(); if(!detector) return; Bool_t group_inconsistency = kFALSE; if(fCreateArray){ if(!fCurrentGroup){ if(detector->GetGroup()) { fCurrentGroup=detector->GetGroup(); } else { fCurrentGroup = new KVGroup; fCurrentGroup->SetNumber(++fGroupNumber); fCurrentGroup->Add(detector); fArray->Add(fCurrentGroup); } } else { KVGroup* det_group = detector->GetGroup(); if(!det_group) { fCurrentGroup->Add(detector); } else { if(det_group!=fCurrentGroup){ // Warning("ParticleEntersNewVolume", // "Detector %s : already belongs to %s, now seems to be in %s", // detector->GetName(), det_group->GetName(), // fCurrentGroup->GetName()); group_inconsistency = kTRUE; } } } } detector->GetNode()->SetName(detector->GetName()); if(fLastDetector && detector!=fLastDetector && !group_inconsistency) { fLastDetector->GetNode()->AddBehind(detector); detector->GetNode()->AddInFront(fLastDetector); } fLastDetector = detector; }
void KVINDRAUpDater::SetChIoSiPedestals(KVDBRun* kvrun) { //read Chio-Si-Etalons pedestals if (!kvrun->GetKey("Pedestals")) return; if (!kvrun->GetKey("Pedestals")->GetLinks()) return; if (!kvrun->GetKey("Pedestals")->GetLinks()->At(0)) return; ifstream file_pied_chiosi; if (!KVBase:: SearchAndOpenKVFile(kvrun->GetKey("Pedestals")->GetLinks()->At(0)-> GetName(), file_pied_chiosi, fDataSet.Data())) { Error("SetPedestals", "Problem opening file %s", kvrun->GetKey("Pedestals")->GetLinks()->At(0)->GetName()); return; } cout << "--> Setting Pedestals" << endl; cout << " ChIo/Si/Etalons: " << kvrun->GetKey("Pedestals")-> GetLinks()->At(0)->GetName() << endl; //skip first 5 lines - header TString line; for (int i = 5; i; i--) { line.ReadLine(file_pied_chiosi); } int cou, mod, type, n_phys, n_gene; float ave_phys, sig_phys, ave_gene, sig_gene; while (file_pied_chiosi.good()) { file_pied_chiosi >> cou >> mod >> type >> n_phys >> ave_phys >> sig_phys >> n_gene >> ave_gene >> sig_gene; KVDetector* det = GetINDRA()->GetDetectorByType(cou, mod, type); if (det) { switch (type) { case ChIo_GG: det->SetPedestal("GG", ave_gene); break; case ChIo_PG: det->SetPedestal("PG", ave_gene); break; case Si_GG: det->SetPedestal("GG", ave_gene); break; case Si_PG: det->SetPedestal("PG", ave_gene); break; case SiLi_GG: det->SetPedestal("GG", ave_gene); break; case SiLi_PG: det->SetPedestal("PG", ave_gene); break; case Si75_GG: det->SetPedestal("GG", ave_gene); break; case Si75_PG: det->SetPedestal("PG", ave_gene); break; default: break; } } } file_pied_chiosi.close(); }
void KVINDRAUpDater::SetLitEnergyCsIParameters(KVDBRun* kvrun) { // Setting Light- Energy CsI calibration parameters for Z=1 KVRList* param_list = kvrun->GetLinks("Light-Energy CsI Z=1"); if (param_list && param_list->GetSize()) { KVDetector* kvd; KVDBParameterSet* kvps; KVCalibrator* kvc; TIter next_ps(param_list); TString str; while ((kvps = (KVDBParameterSet*) next_ps())) { // boucle sur les parametres str = kvps->GetName(); kvd = fArray->GetDetector(str.Data()); if (!kvd) Warning("SetLitEnergyCsIParameters(UInt_t)", "Dectector %s not found !", str.Data()); else { // detector found kvc = kvd->GetCalibrator(kvps->GetTitle()); if (!kvc) { Warning("SetLitEnergyCsIParameters(UInt_t)", "Calibrator %s %s not found ! - it will be created", kvps->GetName(), kvps->GetTitle()); kvd->SetCalibrators(); kvc = kvd->GetCalibrator(kvps->GetTitle()); } for (Int_t i = 0; i < kvc->GetNumberParams(); i++) { kvc->SetParameter(i, kvps->GetParameter(i)); kvc->SetStatus(kTRUE); // calibrator ready } } //detector found } //boucle sur les parameters } // Setting Light- Energy CsI calibration parameters for Z>1 param_list = kvrun->GetLinks("Light-Energy CsI Z>1"); if (!param_list || !param_list->GetSize()) { return; } KVDetector* kvd; KVDBParameterSet* kvps; KVCalibrator* kvc; TString str; TIter next_ps2(param_list); while ((kvps = (KVDBParameterSet*) next_ps2())) { // boucle sur les parametres str = kvps->GetName(); kvd = fArray->GetDetector(str.Data()); if (!kvd) Warning("SetLitEnergyCsIParameters(UInt_t)", "Dectector %s not found !", str.Data()); else { // detector found kvc = kvd->GetCalibrator(kvps->GetTitle()); if (!kvc) { Warning("SetLitEnergyCsIParameters(UInt_t)", "Calibrator %s %s not found ! - it will be created", kvps->GetName(), kvps->GetTitle()); kvd->SetCalibrators(); kvc = kvd->GetCalibrator(kvps->GetTitle()); } for (Int_t i = 0; i < kvc->GetNumberParams(); i++) { kvc->SetParameter(i, kvps->GetParameter(i)); kvc->SetStatus(kTRUE); // calibrator ready } } //detector found } //boucle sur les parameters }
//_______________________________________________________________// void KVINDRAUpDater::CheckStatusOfDetectors(KVDBRun* kvrun) { KVRList* absdet = kvrun->GetLinks("Absent Detectors"); KVRList* oooacq = kvrun->GetLinks("OoO ACQPars"); KVRList* ooodet = kvrun->GetLinks("OoO Detectors"); TIter next(fArray->GetDetectors()); KVDetector* det; KVACQParam* acq; Int_t ndet_absent = 0; Int_t ndet_ooo = 0; Int_t nacq_ooo = 0; while ((det = (KVDetector*)next())) { //Test de la presence ou non du detecteur if (!absdet) { det->SetPresent(); } else { if (absdet->FindObject(det->GetName(), "Absent Detector")) { det->SetPresent(kFALSE); ndet_absent += 1; } else { det->SetPresent(); } } if (det->IsPresent()) { //Test du bon fonctionnement ou non du detecteur if (!ooodet) { det->SetDetecting(); } else { if (ooodet->FindObject(det->GetName(), "OoO Detector")) { det->SetDetecting(kFALSE); ndet_ooo += 1; } else { det->SetDetecting(); } } //Test du bon fonctionnement ou non des parametres d acquisition if (det->IsDetecting()) { TIter next_acq(det->GetACQParamList()); if (!oooacq) { while ((acq = (KVACQParam*)next_acq())) { acq->SetWorking(); } } else { Int_t noff = 0; while ((acq = (KVACQParam*)next_acq())) { if (oooacq->FindObject(acq->GetName(), "OoO ACQPar")) { acq->SetWorking(kFALSE); noff += 1; nacq_ooo += 1; } else { acq->SetWorking(); } } if (noff == 3) { det->SetDetecting(kFALSE); ndet_ooo += 1; nacq_ooo -= 3; } } } } } Info("KVINDRAUpDater", "%d detecteurs absents", ndet_absent); Info("KVINDRAUpDater", "%d detecteurs ne fonctionnent pas", ndet_ooo); Info("KVINDRAUpDater", "%d parametres d acquisition ne fonctionnent pas", nacq_ooo); }
TGraph* KVIDTelescope::MakeIDLine(KVNucleus* nuc, Double_t Emin, Double_t Emax, Double_t Estep) { //For a given nucleus, generate a TGraph representing the line in the deltaE-E //plane of the telescope which can be associated with nuclei of this (A,Z) with total //incident energies between the two limits. //NOTE: if there are other absorbers/detectors placed before this telescope, //the energy losses of the particle in these will be taken into account. //If the step in energy is not given, it is taken equal to 100 equal steps between min and max. //The TGraph should be deleted by the user after use. if (!Estep) Estep = (Emax - Emin) / 100.; Int_t nsteps = 1 + (Int_t)((Emax - Emin) / Estep); if (nsteps < 1) return 0; Double_t* y = new Double_t[nsteps]; Double_t* x = new Double_t[nsteps]; Int_t step = 0; //get list of all detectors through which particle must pass in order to reach //2nd member of ID Telescope TList* detectors = GetDetector(2)->GetAlignedDetectors(KVGroup::kForwards); //detectors->ls(); TIter next_det(detectors); //cout << "nsteps =" << nsteps << endl; for (Double_t E = Emin; E <= Emax; E += Estep) { //Set energy of nucleus nuc->SetEnergy(E); //cout << "Einc=" << E << endl; //Calculate energy loss in each member and stock in arrays x & y //first member KVDetector* det = 0; x[step] = y[step] = -1; while ((det = (KVDetector*) next_det())) { //det->Print(); Double_t eloss = det->GetELostByParticle(nuc); if (det == GetDetector(1)) y[step] = eloss; else if (det == GetDetector(2)) x[step] = eloss; Double_t E1 = nuc->GetEnergy() - eloss; nuc->SetEnergy(E1); //cout << "Eloss=" << eloss << endl; //cout << "Enuc=" << nuc->GetEnergy() << endl; if (E1 < 1.e-3) break; } //cout << "step = " << step << " x = " << x[step] << " y = " << y[step] << endl; //make sure that some energy is lost in each member //otherwise miss a step and reduce number of points in graph if (x[step] > 0 && y[step] > 0) { step++; } else { nsteps--; } //cout << "nsteps =" << nsteps << endl; //reset iterator ready for next loop on detectors next_det.Reset(); } TGraph* tmp = 0; if (nsteps > 1) tmp = new TGraph(nsteps, x, y); delete[]x; delete[]y; return tmp; }
void KVINDRA::CreateROOTGeometry() { // Overrides KVASMultiDetArray::CreateGeoManager in order to use INDRAGeometryBuilder // which builds the TGeo representation of INDRA using the Y. Huguet CAO data. // // The optional arguments (dx,dy,dz) are the half-lengths in centimetres of the "world"/"top" volume // into which all the detectors of the array are placed. This should be big enough so that all detectors // fit in. The default values of 500 give a "world" which is a cube 1000cmx1000cmx1000cm (with sides // going from -500cm to +500cm on each axis). // // If closegeo=kFALSE we leave the geometry open for other structures to be added. if (!IsBuilt()) { Error("CreateROOTGeometry", "gIndra has to be build first"); return; } if (!GetNavigator()) { //Error("CreateROOTGeometry","No existing navigator"); return; SetNavigator(new KVRangeTableGeoNavigator(gGeoManager, KVMaterial::GetRangeTable())); GetNavigator()->SetNameCorrespondanceList("INDRA.names"); } // set up shape & matrix pointers in detectors Info("CreateROOTGeometry", "Scanning geometry shapes and matrices..."); KVGeoImport gimp(gGeoManager, KVMaterial::GetRangeTable(), this, kFALSE); gimp.SetNameCorrespondanceList("INDRA.names"); KVEvent* evt = new KVEvent(); KVNucleus* nuc = evt->AddParticle(); nuc->SetZAandE(1, 1, 1); KVINDRADetector* det; TIter next(GetDetectors()); Int_t nrootgeo = 0; while ((det = (KVINDRADetector*)next())) { nuc->SetTheta(det->GetTheta()); nuc->SetPhi(det->GetPhi()); gimp.SetLastDetector(0); gimp.PropagateEvent(evt); if (!(det->GetActiveLayerShape() && det->GetActiveLayerMatrix())) { Info("CreateROOTGeometry", "Volume checking for %s", det->GetName()); Double_t theta0 = det->GetTheta(); Double_t phi0 = det->GetPhi(); for (Double_t TH = theta0 - 0.5; TH <= theta0 + 0.5; TH += 0.1) { for (Double_t PH = phi0 - 10; PH <= phi0 + 10; PH += 1) { nuc->SetTheta(TH); nuc->SetPhi(PH); gimp.SetLastDetector(0); gimp.PropagateEvent(evt); if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()) break; } if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()) break; } } if (!(det->GetActiveLayerShape() && det->GetActiveLayerMatrix())) { Info("CreateROOTGeometry", "Volume checking failed for : %s", det->GetName()); } // check etalon trajectories (if etalons are present) if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix() && det->GetRingNumber() > 9) { if (GetDetector(Form("SI75_%d", det->GetRingNumber())) || GetDetector(Form("SILI_%d", det->GetRingNumber()))) { if ((det->IsCalled("CSI_1002") || det->IsCalled("CSI_1102") || det->IsCalled("CSI_1202") || det->IsCalled("CSI_1304") || det->IsCalled("CSI_1403") || det->IsCalled("CSI_1503") || det->IsCalled("CSI_1602") || det->IsCalled("CSI_1702")) && det->GetNode()->GetNDetsInFront() < 2) { Info("CreateROOTGeometry", "Trajectory checking for %s", det->GetName()); Double_t theta0 = det->GetTheta(); Double_t phi0 = det->GetPhi(); for (Double_t TH = theta0 - 0.5; TH <= theta0 + 0.5; TH += 0.1) { for (Double_t PH = phi0 - 10; PH <= phi0 + 10; PH += 1) { nuc->SetTheta(TH); nuc->SetPhi(PH); gimp.SetLastDetector(0); gimp.PropagateEvent(evt); if (det->GetNode()->GetNDetsInFront() == 2) break; } if (det->GetNode()->GetNDetsInFront() == 2) break; } } } } nrootgeo += (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()); } delete evt; Info("CreateROOTGeometry", "ROOT geometry initialised for %d/%d detectors", nrootgeo, GetDetectors()->GetEntries()); // Set up trajectories TIter it(GetDetectors()); KVDetector* d; while ((d = (KVDetector*)it())) d->GetNode()->RehashLists();// make sure detector nodes are correct AssociateTrajectoriesAndNodes(); DeduceGroupsFromTrajectories(); FillTrajectoryIDTelescopeLists(); CalculateReconstructionTrajectories(); GetNavigator()->AbsorbDetectorPaths(&gimp); }
void KVINDRAReconEvent::IdentifyEvent() { // Performs event identification (see KVReconstructedEvent::IdentifyEvent), and then // particles stopping in first member of a telescope (GetStatus() == KVReconstructedNucleus::kStatusStopFirstStage) are // labelled with VEDA ID code kIDCode5 (Zmin) // // When CsI identification gives a gamma, we unset the 'analysed' state of all detectors // in front of the CsI and reanalyse the group in order to reconstruct and identify charged particles // stopping in them. // // Unidentified particles receive the general ID code for non-identified particles (kIDCode14) KVReconstructedEvent::IdentifyEvent(); KVINDRAReconNuc* d = 0; int mult = GetMult(); KVUniqueNameList gammaGroups;//list of groups with gammas identified in CsI ResetGetNextParticle(); while ((d = GetNextParticle())) { if (d->IsIdentified() && d->GetStatus() == KVReconstructedNucleus::kStatusStopFirstStage) { d->SetIDCode(kIDCode5); // Zmin } else if (d->IsIdentified() && d->GetCodes().TestIDCode(kIDCode0)) { // gamma identified in CsI // reset analysed state of all detectors in front of CsI if (d->GetCsI()) { if (d->GetCsI()->GetAlignedDetectors()) { TIter next(d->GetCsI()->GetAlignedDetectors()); KVDetector* det = (KVDetector*)next(); //first detector = CsI while ((det = (KVDetector*)next())) det->SetAnalysed(kFALSE); gammaGroups.Add(d->GetGroup()); } else { Error("IdentifyEvent", "particule id gamma, no aligned detectors???"); d->Print(); } } else { Error("IdentifyEvent", "particule identified as gamma, has no CsI!!"); d->Print(); } } } // perform secondary reconstruction in groups with detected gammas int ngamG = gammaGroups.GetEntries(); if (ngamG) { for (int i = 0; i < ngamG; i++) { gIndra->AnalyseGroupAndReconstructEvent(this, (KVGroup*)gammaGroups.At(i)); } } if (GetMult() > mult) { /*Info("IdentifyEvent", "Event#%d: Secondary reconstruction (gammas) -> %d new particles", GetNumber(), GetMult()-mult);*/ // identify new particles generated in secondary reconstruction KVReconstructedEvent::IdentifyEvent(); ResetGetNextParticle(); while ((d = GetNextParticle())) { if (d->IsIdentified() && d->GetStatus() == KVReconstructedNucleus::kStatusStopFirstStage) { d->SetIDCode(kIDCode5); // Zmin } else if (!d->IsIdentified()) { d->SetIDCode(kIDCode14); } } /* for(int i=mult+1; i<=GetMult(); i++){ d = GetParticle(i); if(d->IsIdentified()) printf("\t%2d: Ring %2d Module %2d Z=%2d A=%3d code=%d\n",i,d->GetRingNumber(), d->GetModuleNumber(),d->GetZ(),d->GetA(),d->GetCodes().GetVedaIDCode()); else printf("\t%2d: Ring %2d Module %2d UNIDENTIFIED status=%d\n", i,d->GetRingNumber(), d->GetModuleNumber(), d->GetStatus()); } */ } }
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); }
KVDetector* KVGeoImport::GetCurrentDetector() { // Returns pointer to KVDetector corresponding to current location // in geometry. Detector is created and added to array if needed. // We also set up any geometry structure elements (from nodes beginning with "STRUCT_") KVString detector_name; Bool_t multilay; TGeoVolume* detector_volume = GetCurrentDetectorNameAndVolume(detector_name,multilay); // failed to identify current volume as part of a detector if(!detector_volume) return 0; // has detector already been built ? if not, do it now KVDetector* det = fArray->GetDetector(detector_name); if(!fCreateArray){ if(det){ // set matrix & shape for entrance window if not done yet if(!det->GetEntranceWindowMatrix()){ det->SetEntranceWindowMatrix(GetCurrentMatrix()); det->SetEntranceWindowShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // set matrix & shape for active layer det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } } } else { if(!det) { det = BuildDetector(detector_name, detector_volume); if(det) { // Setting the entrance window shape and matrix // ============================================ // for consistency, the matrix and shape MUST correspond // i.e. we cannot have the matrix corresponding to the entrance window // of a multilayer detector and the shape corresponding to the // whole detector (all layers) - otherwise, calculation of points // on detector entrance window will be false! // Info("GetCurrentDetector","Setting EW matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetEntranceWindowMatrix(GetCurrentMatrix()); det->SetEntranceWindowShape((TGeoBBox*)GetCurrentVolume()->GetShape()); TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // first layer of detector (or only layer) is also active layer // Info("GetCurrentDetector","and also setting active layer matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } fArray->Add(det); Int_t nstruc = CurrentStructures().GetEntries(); if(nstruc){ // Build and add geometry structure elements KVGeoStrucElement* ELEM = fArray; for(register int i=0;i<nstruc;i++){ KVGeoStrucElement* elem = (KVGeoStrucElement*)CurrentStructures()[i]; KVGeoStrucElement* nextELEM = ELEM->GetStructure(elem->GetName()); if(!nextELEM){ // make new structure nextELEM = new KVGeoStrucElement(elem->GetName(), elem->GetType()); nextELEM->SetNumber(elem->GetNumber()); ELEM->Add(nextELEM); } ELEM=nextELEM; } // add detector to last structure ELEM->Add(det); } } } else { // Detector already built, are we now in its active layer ? TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // Info("GetCurrentDetector","Setting active layer matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } } } return det; }