er  dev
ERBeamDetTrackFinder.cxx
1 /********************************************************************************
2  * Copyright (C) Joint Institute for Nuclear Research *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 
9 #include "ERBeamDetTrackFinder.h"
10 
11 #include "TVector3.h"
12 #include "TMath.h"
13 #include "TGeoNode.h"
14 #include "TGeoManager.h"
15 
16 #include "FairRootManager.h"
17 #include "FairRun.h"
18 #include "FairRuntimeDb.h"
19 #include "FairLogger.h"
20 
21 #include "ERRunAna.h"
22 #include "ERDigi.h"
23 
24 //--------------------------------------------------------------------------------------------------
26  : ERTask("ER BeamDet track finding scheme")
27 {
28  fAvailibleRunManagers.push_back("ERRunAna");
29 }
30 //--------------------------------------------------------------------------------------------------
32  : ERTask("ER BeamDet track finding scheme ", verbose)
33 {
34  fAvailibleRunManagers.push_back("ERRunAna");
35 }
36 //--------------------------------------------------------------------------------------------------
38  if (ERTask::Init() != kSUCCESS)
39  return kFATAL;
40  // Get input array
41  FairRootManager* ioman = FairRootManager::Instance();
42  if ( ! ioman ) Fatal("Init", "No FairRootManager");
43  if (interaction_volume_name_ == "")
44  Fatal("Init", "TargetVolumeName for ERBeamDetTrackFinder not defined! ");
45  fBeamDetMWPCDigiX1 = (TClonesArray*) ioman->GetObject("BeamDetMWPCDigiX1");
46  fBeamDetMWPCDigiX2 = (TClonesArray*) ioman->GetObject("BeamDetMWPCDigiX2");
47  fBeamDetMWPCDigiY1 = (TClonesArray*) ioman->GetObject("BeamDetMWPCDigiY1");
48  fBeamDetMWPCDigiY2 = (TClonesArray*) ioman->GetObject("BeamDetMWPCDigiY2");
49  // Register output array fBeamDetHits
50  fBeamDetTrack = new TClonesArray("ERBeamDetTrack", consts::approx_beamdet_track_number);
51  //fBeamDetTrack = (ERBeamDetTrack*)new ERBeamDetTrack();
52  ioman->Register("BeamDetTrack", "BeamDet track", fBeamDetTrack, kTRUE);
53  fBeamDetSetup = ERBeamDetSetup::Instance();
54  fBeamDetSetup->SetParContainers();
55  fBeamDetSetup->GetGeoParamsFromParContainer();
56  fRand = new TRandom3();
57  return kSUCCESS;
58 }
59 //--------------------------------------------------------------------------------------------------
60 Bool_t ERBeamDetTrackFinder::IsCluster(TClonesArray* digiArray) {
61  Bool_t isCluster = kTRUE;
62  for(Int_t i = 0; i < digiArray->GetEntries() - 1; i++) {
63  ERDigi* digi = (ERDigi*)digiArray->At(i);
64  ERDigi* digiNeigborWire = (ERDigi*)digiArray->At(i + 1);
65  if((digiNeigborWire->Channel() - digi->Channel()) != 1) {
66  isCluster = kFALSE;
67  FairRun* run = FairRun::Instance();
68  break;
69  }
70  }
71  return isCluster;
72 }
73 //--------------------------------------------------------------------------------------------------
74 Double_t ERBeamDetTrackFinder::CalcCoordinateAvg(const TString& digi_branch_name,
75  const TClonesArray* digis, char coordType) {
76  if (!digis->GetEntriesFast())
77  LOG(FATAL) << "ERBeamDetTrackFinder::CalcCoordinateAvg: empty digi collection"
78  << FairLogger::endl;
79  ERChannel channel_of_first_digi = dynamic_cast<ERDigi*>(digis->At(0))->Channel();
80  ERChannel channel_of_last_digi = channel_of_first_digi;
81  for (int iDigi(0); iDigi < digis->GetEntriesFast(); ++iDigi) {
82  const auto channel = dynamic_cast<ERDigi*>(digis->At(iDigi))->Channel();;
83  if (channel < channel_of_first_digi)
84  channel_of_first_digi = channel;
85  if (channel > channel_of_last_digi)
86  channel_of_last_digi = channel;
87  }
88  switch (coordType) {
89  case 'X':
90  return 0.5*(fBeamDetSetup->GetWireGlobX(digi_branch_name, channel_of_first_digi-1)
91  + fBeamDetSetup->GetWireGlobX(digi_branch_name, channel_of_last_digi-1));
92  case 'Y':
93  return 0.5*(fBeamDetSetup->GetWireGlobY(digi_branch_name, channel_of_first_digi-1)
94  + fBeamDetSetup->GetWireGlobY(digi_branch_name, channel_of_last_digi-1));
95  case 'Z':
96  return 0.5*(fBeamDetSetup->GetWireGlobZ(digi_branch_name, channel_of_first_digi-1)
97  + fBeamDetSetup->GetWireGlobZ(digi_branch_name, channel_of_last_digi-1));
98  default:
99  LOG(FATAL) << "ERBeamDetTrackFinder::CalcCoordinateAvg: Unknown coordinate type "
100  << FairLogger::endl;
101  }
102 }
103 //--------------------------------------------------------------------------------------------------
104 void ERBeamDetTrackFinder::Exec(Option_t* opt) {
105  Reset();
106  LOG(DEBUG) << "[ERBeamDetTrackFinder]------------Started-----------------------------------------"
107  << FairLogger::endl;
108 
109  if(fBeamDetMWPCDigiX1->GetEntriesFast() < 1 ||
110  fBeamDetMWPCDigiX2->GetEntriesFast() < 1 ||
111  fBeamDetMWPCDigiY1->GetEntriesFast() < 1 ||
112  fBeamDetMWPCDigiY2->GetEntriesFast() < 1 ) {
113  LOG(DEBUG) << "Multiplicity less than one" << FairLogger::endl;
114  //fRun->MarkFill(kFALSE);
115  return ;
116  }
117 
118  Double_t xFar, yFar, zFar;
119  Double_t xClose, yClose, zClose;
120  Double_t coordinate;
121 
122  Bool_t cluster;
123  ERDigi* digi;
124  // Check X1 cluster
125  if(fBeamDetMWPCDigiX1->GetEntriesFast() > 1) { // If multiplicity in wires array is more than one
126  cluster = IsCluster(fBeamDetMWPCDigiX1); // check that all wires in array have are neigbours
127  if(cluster) {
128  // calculate average coordinate of wires
129  xFar = ERBeamDetTrackFinder::CalcCoordinateAvg("BeamDetMWPCDigiX1", fBeamDetMWPCDigiX1, 'X');
130  zFar = ERBeamDetTrackFinder::CalcCoordinateAvg("BeamDetMWPCDigiX1", fBeamDetMWPCDigiX1, 'Z');
131  } else {
132  //fRun->MarkFill(kFALSE);
133  return;
134  }
135  } else { // only one wire in array
136  digi = (ERDigi*)fBeamDetMWPCDigiX1->At(0);
137  xFar = fBeamDetSetup->GetWireGlobX("BeamDetMWPCDigiX1", digi->Channel()-1);
138  xFar = fBeamDetSetup->GetWireGlobX("BeamDetMWPCDigiX1", digi->Channel()-1);
139  zFar = fBeamDetSetup->GetWireGlobZ("BeamDetMWPCDigiX1", digi->Channel()-1);
140  }
141 
142  // Check X2 cluster
143  if(fBeamDetMWPCDigiX2->GetEntriesFast() > 1) { // If multiplicity in wires array is more than one
144  cluster = IsCluster (fBeamDetMWPCDigiX2); // check that all wires in array have are neigbours
145  if(cluster) {
146  // calculate average coordinate of wires
147  xClose = ERBeamDetTrackFinder::CalcCoordinateAvg("BeamDetMWPCDigiX2",fBeamDetMWPCDigiX2, 'X');
148  } else {
149  //fRun->MarkFill(kFALSE);
150  return;
151  }
152  } else { // only one wire in array
153  digi = (ERDigi*)fBeamDetMWPCDigiX2->At(0);
154  xClose = fBeamDetSetup->GetWireGlobX("BeamDetMWPCDigiX2", digi->Channel()-1);
155  }
156  // Check Y1 cluster
157  if(fBeamDetMWPCDigiY1->GetEntriesFast() > 1 ) { // If multiplicity in wires array is more than one
158  cluster = IsCluster (fBeamDetMWPCDigiY1); // check that all wires in array have are neigbours
159  if(cluster) {
160  // calculate average coordinate of wires
161  yFar = ERBeamDetTrackFinder::CalcCoordinateAvg("BeamDetMWPCDigiY1", fBeamDetMWPCDigiY1, 'Y');
162  } else {
163  //fRun->MarkFill(kFALSE);
164  return;
165  }
166  } else { // only one wire in array
167  digi = (ERDigi*)fBeamDetMWPCDigiY1->At(0);
168  yFar = fBeamDetSetup->GetWireGlobY("BeamDetMWPCDigiY1", digi->Channel()-1);
169  }
170  // Check Y2 cluster
171  if(fBeamDetMWPCDigiY2->GetEntriesFast() > 1 ) { // If multiplicity in wires array is more than one
172  cluster = IsCluster(fBeamDetMWPCDigiY2); // check that all wires in array have are neigbours
173  if(cluster) {
174  // calculate average coordinate of wires
175  yClose = ERBeamDetTrackFinder::CalcCoordinateAvg("BeamDetMWPCDigiY2", fBeamDetMWPCDigiY2, 'Y');
176  zClose = ERBeamDetTrackFinder::CalcCoordinateAvg("BeamDetMWPCDigiY2", fBeamDetMWPCDigiY2, 'Z');
177  } else {
178  //fRun->MarkFill(kFALSE);
179  return;
180  }
181  } else { // only one wire in array
182  digi = (ERDigi*)fBeamDetMWPCDigiY2->At(0);
183  yClose = fBeamDetSetup->GetWireGlobY("BeamDetMWPCDigiY2", digi->Channel()-1);
184  zClose = fBeamDetSetup->GetWireGlobZ("BeamDetMWPCDigiY2", digi->Channel()-1);
185  }
186  TVector3 hitFar(xFar, yFar, zFar);
187  TVector3 hitClose(xClose, yClose, zClose);
188  TVector3 vectorOnTarget = hitClose - hitFar;
189 
190  LOG(DEBUG) << "Theta = " << vectorOnTarget.Theta() << "; Phi = " << vectorOnTarget.Phi() << FairLogger::endl;
191 
192  Double_t xTarget = xClose - zClose*TMath::Tan(vectorOnTarget.Theta())*TMath::Cos(vectorOnTarget.Phi());
193  Double_t yTarget = yClose - zClose*TMath::Tan(vectorOnTarget.Theta())*TMath::Sin(vectorOnTarget.Phi());
194 
195  LOG(DEBUG) << "xFar = " << xFar << "; yFar = " << yFar << "; zFar = " << zFar
196  << "xClose = " << xClose << "; yClose = " << yClose << "; zClose = " << zClose << FairLogger::endl;
197 
198  TGeoNode* node;
199  node = gGeoManager->InitTrack(xClose, yClose, zClose, vectorOnTarget.Unit().X(),
200  vectorOnTarget.Unit().Y(),
201  vectorOnTarget.Unit().Z());
202  Double_t targetMiddleThicknessX;
203  Double_t targetMiddleThicknessY;
204  Double_t targetMiddleThicknessZ;
205 
206  Bool_t target_affected = kFALSE;
207  while(!gGeoManager->IsOutside()){
208  node = gGeoManager->FindNextBoundaryAndStep();
209  if (!node)
210  break;
211  if ((TString(node->GetName()).Contains(interaction_volume_name_))) {
212  target_affected = kTRUE;
213  break;
214  }
215  }
216  if (!target_affected){
217  LOG(WARNING) << "Target is not affected" << FairLogger::endl;
218  return;
219  }
220 
221  node = gGeoManager->FindNextBoundary();
222 
223  const double max_track_range_in_interaction_volume = gGeoManager->GetStep();
224  gGeoManager->SetStep(max_track_range_in_interaction_volume * depth_ratio_);
225  gGeoManager->Step();
226 
227  targetMiddleThicknessX = gGeoManager->GetCurrentPoint()[0];
228  targetMiddleThicknessY = gGeoManager->GetCurrentPoint()[1];
229  targetMiddleThicknessZ = gGeoManager->GetCurrentPoint()[2];
230 
231  AddTrack(targetMiddleThicknessX,
232  targetMiddleThicknessY,
233  targetMiddleThicknessZ, vectorOnTarget.Unit());
234 
235  LOG(DEBUG) << "Point on target " << "(" << targetMiddleThicknessX << ", "
236  << targetMiddleThicknessY << ", "
237  << targetMiddleThicknessZ << ") cm"
238  << FairLogger::endl;
239  LOG(DEBUG) << "[ERBeamDetTrackFinder]------------Finished-----------------------------------------"
240  << FairLogger::endl;
241 }
242 //--------------------------------------------------------------------------------------------------
244  if (fBeamDetTrack) {
245  fBeamDetTrack->Clear();
246  }
247 }
248 //--------------------------------------------------------------------------------------------------
249 ERBeamDetTrack* ERBeamDetTrackFinder::AddTrack(Double_t xt, Double_t yt, Double_t zt, TVector3 v)
250 {
251  return new((*fBeamDetTrack)[fBeamDetTrack->GetEntriesFast()])
252  ERBeamDetTrack(xt, yt, zt, v);
253 }
254 //--------------------------------------------------------------------------------------------------
255 ClassImp(ERBeamDetTrackFinder)
Definition: ERDigi.h:15
virtual void Exec(Option_t *opt)
Defines the transformation actions for all input data (MWPCDigi) to output data (Track) for each even...
Double_t CalcCoordinateAvg(const TString &digi_branch_name, const TClonesArray *digiArray, char coordType)
Calculates an arithmetic average value in array of consequent wires.
virtual InitStatus Init()
Defines all input and output object colletions participates in track finding.
Class for reconsruction ion&#39;s coordinate and momentum direction on target.
ERBeamDetSetup * fBeamDetSetup
access to ERBeamDetSetup class instance
virtual InitStatus Init()
Definition: ERTask.cxx:31
ERBeamDetTrackFinder()
Default constructor.
TClonesArray * fBeamDetMWPCDigiY2
input collection of MWPC Digi
Bool_t IsCluster(TClonesArray *digiArray)
Checks if the collection of digies contatains only neigbour wires.
virtual void Reset()
Resets all output data.
std::vector< TString > fAvailibleRunManagers
Run managers that are availible for this task.
Definition: ERTask.h:64
ERBeamDetTrack * AddTrack(Double_t xt, Double_t yt, Double_t zt, TVector3 v)
Adds a ERBeamDetTrack to the output Collection.
TClonesArray * fBeamDetTrack
output collection of tracks
Base abstract class for all tasks in er.
Definition: ERTask.h:27