map<int,vector<double> > RPCChambersCluster::getReconstructedHits(vector<unsigned> vectorOfReferenceChambers, const int & timeWindow,const int & timeReference,bool & isVerticalTrack,map<int,double> & scintilatorsCoordinates,const bool & keepRecoTrack,TFile * fileForRecoTracks,const int & eventNum,const double & correlationFactor, const ESiteFileType & fileType){ // map<int,vector<double> > mapOfHits; // // the default value for Chi2goodness is 20 //double best_chi2goodnes_value = Chi2goodness+10 ; // this variable is used as reference so that it holds the best chi2 found for a track, so its used only a track with better chi2 to be accepted double currentBestCorrFact = -2; int lastFitPoint = 0; for (int i = 0 ; i < this->getNumberOfChambers() ; i++){ this->getChamberNumber(i+1)->findAllClustersForTriggerTimeReferenceAndTimeWindow(timeReference,timeWindow,5); //cout << "Chamber is " << i+1 << endl; } vector<vector<int> > vectorOfClusterNumberCombinations; if (fileType == kIsCERNrawFile ){ assert(vectorOfReferenceChambers.size() == 3 ); lastFitPoint = 9; for ( int i = 0 ; i < this->getChamberNumber(vectorOfReferenceChambers[0])->getNumberOfClusters() ; i++ ){ for( int j = 0 ; j < this->getChamberNumber(vectorOfReferenceChambers[1])->getNumberOfClusters() ; j++ ){ for( int k = 0 ; k < this->getChamberNumber(vectorOfReferenceChambers[vectorOfReferenceChambers.size()-1])->getNumberOfClusters() ; k++ ){ vector<int> singleCombination; singleCombination.push_back(i+1); singleCombination.push_back(j+1); singleCombination.push_back(k+1); for (int f = 0 ; f < singleCombination.size() ; f++){ if(this->getChamberNumber(vectorOfReferenceChambers[f])->getSizeOfCluster(singleCombination.at(f)) > 5 ) continue; // don't insert combination if there is too big cluster. } vectorOfClusterNumberCombinations.push_back(singleCombination); } } } } if (fileType == kIsBARCrawFile || fileType == kIsGENTrawFile ){ // add implementation for BARC and Ghent stand . lastFitPoint = 5; assert(vectorOfReferenceChambers.size() == 2); for ( int i = 0 ; i < this->getChamberNumber(vectorOfReferenceChambers[0])->getNumberOfClusters() ; i++ ){ for( int j = 0 ; j < this->getChamberNumber(vectorOfReferenceChambers[1])->getNumberOfClusters() ; j++ ){ vector<int> singleCombination; singleCombination.push_back(i+1); singleCombination.push_back(j+1); for (int f = 0 ; f < singleCombination.size() ; f++){ if(this->getChamberNumber(vectorOfReferenceChambers[f])->getSizeOfCluster(singleCombination.at(f)) > 5 ) continue; // don't insert combination if there is too big cluster. } vectorOfClusterNumberCombinations.push_back(singleCombination); } } } string topScintToString, botScintToString; for (int combinationsVectorElement = 0 ; combinationsVectorElement < vectorOfClusterNumberCombinations.size() ; combinationsVectorElement ++){ // the partition logic start here - track could pass more than one partition int direction = 0 ; // direction should describe how the partition changes from one reference chamber to another. It vector<int> RefChamberClusterPartition; bool positive = false; bool negative = false; int partitionPenetrated = 1; // the Y coordinate is the partition number (1 2 or 3 - A B or C) vector<int> clusterNum = vectorOfClusterNumberCombinations.at(combinationsVectorElement); for (int ii = 0; ii < clusterNum.size() ; ii++){ RefChamberClusterPartition.push_back(this->getChamberNumber(vectorOfReferenceChambers[ii])->getXYCoordinatesOfCluster(clusterNum.at(ii)).at(1)); } isVerticalTrack = true; for ( int ii = 0; ii < RefChamberClusterPartition.size() - 1 ; ii++ ){ direction = (RefChamberClusterPartition.at(ii) - RefChamberClusterPartition.at(ii+1)); if (direction != 0) { direction = direction/abs(direction); partitionPenetrated++; } // get only the sign ( +1 or -1) if (direction && direction == -1) { positive = true; isVerticalTrack = false; } if (direction && direction == 1 ) { negative = true; isVerticalTrack = false; } } if ( positive && negative ) continue; // cannot have a track that goes in both direction /* TH1F * histXZ = new TH1F("fitHistogram","XZ plane",110,0,11); histXZ->GetYaxis()->SetRangeUser(-20,52); histXZ->SetMarkerColor(kBlue); histXZ->SetMarkerStyle(kCircle); histXZ->GetXaxis()->SetTitle("Shelf number"); histXZ->GetYaxis()->SetTitle("Channel number"); */ TF1 * fitfunc = new TF1("FitTrack","[0]+x*[1]",0,lastFitPoint+1); TGraphErrors * graphXZ = new TGraphErrors(); graphXZ->GetXaxis()->SetTitle("Shelf number"); graphXZ->GetYaxis()->SetTitle("Channel number"); //graphXZ->SetLineColor(0); graphXZ->SetMarkerColor(kBlack); graphXZ->SetMarkerStyle(kFullCircle); graphXZ->SetName("fit graph"); graphXZ->SetTitle("XZ plane"); graphXZ->GetXaxis()->SetTitle("Muon station"); graphXZ->GetYaxis()->SetTitle("Channel number"); fitfunc->SetLineColor(kBlue); vector<double> coordinates; double xCoordinate = 0; int yCoordinate = 0; int zCoorinate = 0; for (int ii=0 ; ii < vectorOfReferenceChambers.size() ; ii++){ coordinates = this->getChamberNumber(vectorOfReferenceChambers[ii])->getXYCoordinatesOfCluster(clusterNum[ii]); xCoordinate = coordinates.at(0); yCoordinate = coordinates.at(1); zCoorinate = 10*vectorOfReferenceChambers[ii]; Double_t errorValue = this->getChamberNumber(vectorOfReferenceChambers[ii])->getSizeOfCluster(clusterNum[ii]); // histXZ->SetBinContent(zCoorinate,xCoordinate); // histXZ->SetBinError(zCoorinate,errorValue/2); //cout << xCoordinate << " " << yCoordinate << endl; graphXZ->SetPoint(ii,vectorOfReferenceChambers[ii],xCoordinate); graphXZ->SetPointError(ii,0,errorValue/2); } Double_t params[2]; graphXZ->Fit(fitfunc,"RFQ"); fitfunc->GetParameters(params); //cout << "par1 " << params[0] << " par2 " << params[1] << " chi2 " << fitfunc->GetChisquare() << endl; // The resudials - difference between estimated fit value and the middle of the nearest cluster int prevReference = 0 , nextReference = 0 , prevReferencePartition = 0 , nextReferencePartition = 0; bool currentChamberIsReference = false; int startCounter = 0, endCounter = 0; if ( abs(graphXZ->GetCorrelationFactor()) >= correlationFactor && abs(graphXZ->GetCorrelationFactor()) > currentBestCorrFact ) { // in case of only one partition, get the partition number of the first reference point currentBestCorrFact = abs(graphXZ->GetCorrelationFactor()); int referenceChambersIncrementor = 0; bool negativeChannelNumberIsFound = false; // --------- for ( int currentChNumber = 0 ; currentChNumber < this->getNumberOfChambers() ; currentChNumber++ ) { // check where the chamber is according to the reference chambers vector<double> vectorOfpartitionsAndHit; double channelNum = fitfunc->Eval(currentChNumber+1); /** four cases 1. the chamber is before the first reference 2. the chamber is after the last reference 3. the chamber is between two references 4. the chamber is a reference */ for(int refCheck = 0 ; refCheck < vectorOfReferenceChambers.size(); refCheck++){ // find the surounding references if (currentChNumber+1 == vectorOfReferenceChambers.at(refCheck)){ currentChamberIsReference = true; break; } if ( vectorOfReferenceChambers.at(refCheck) > currentChNumber+1 && refCheck == 0 ){ // its before the first reference chamber nextReference = vectorOfReferenceChambers.at(refCheck); nextReferencePartition = this->getChamberNumber(nextReference)->getXYCoordinatesOfCluster(clusterNum[refCheck]).at(1); break; } if ( vectorOfReferenceChambers.at(refCheck) < currentChNumber+1 && refCheck == vectorOfReferenceChambers.size() - 1 ){ // its after the last chamber prevReference = vectorOfReferenceChambers.at(refCheck); prevReferencePartition = this->getChamberNumber(prevReference)->getXYCoordinatesOfCluster(clusterNum[refCheck]).at(1); break; } if ( vectorOfReferenceChambers.at(refCheck) < currentChNumber+1 && vectorOfReferenceChambers.at(refCheck+1) > currentChNumber+1 ){ // its between two references prevReference = vectorOfReferenceChambers.at(refCheck) ; nextReference = vectorOfReferenceChambers.at(refCheck+1); prevReferencePartition = this->getChamberNumber(prevReference)->getXYCoordinatesOfCluster(clusterNum[refCheck]).at(1); nextReferencePartition = this->getChamberNumber(nextReference)->getXYCoordinatesOfCluster(clusterNum[refCheck+1]).at(1); break; } } // end of partition possibilities if(!currentChamberIsReference){ if (nextReference && prevReference == 0){ if (positive){ prevReferencePartition = 1; } if(negative){ prevReferencePartition = this->getChamberNumber(1)->getClones(); } } if (prevReferencePartition && nextReferencePartition == 0){ if (positive){ nextReferencePartition = this->getChamberNumber(1)->getClones(); } if(negative){ nextReferencePartition = 1; } } if (partitionPenetrated == 1 ){ prevReferencePartition = yCoordinate; nextReferencePartition = yCoordinate; int firstRef = vectorOfReferenceChambers.at(0); int lastRef = vectorOfReferenceChambers.at(vectorOfReferenceChambers.size() - 1); int ccham = currentChNumber+1; if(! (lastRef > ccham && firstRef < ccham) ){ // all partitions are possible, chambers are out of the reference scope prevReferencePartition = this->getChamberNumber(1)->getClones(); nextReferencePartition = 1; // 3 in case of ecap chamber } } if (positive){ startCounter = prevReferencePartition; endCounter = nextReferencePartition; } else { startCounter = nextReferencePartition ; endCounter = prevReferencePartition ; } for (int currentCounter = startCounter ; currentCounter <= endCounter; currentCounter ++ ){ assert(currentCounter > 0 && currentCounter < 4); vectorOfpartitionsAndHit.push_back(currentCounter); } } else{ vectorOfpartitionsAndHit.push_back(this->getChamberNumber(currentChNumber+1)->getXYCoordinatesOfCluster(clusterNum[referenceChambersIncrementor]).at(1)); referenceChambersIncrementor ++; } prevReference = 0 ; nextReference = 0 ; prevReferencePartition = 0 ; nextReferencePartition = 0; currentChamberIsReference = false; //cout << "Chamber " << l+1 << " " << coordinates.at(1) << " " << fitfunc->Eval(l+1) << " " << endl; int channelNumberToStore = channelNum; if (channelNumberToStore < 96/this->getChamberNumber(1)->getClones()){ channelNumberToStore += 1; } // add one to represent the fired channel, or none if the channel is on the right border vectorOfpartitionsAndHit.push_back(channelNumberToStore); // the last element is the number of the channel // Debug lines /** cout << "Chamber is " << currentChNumber+1 << " partitions " ; for (int thesize = 0 ; thesize < vectorOfpartitionsAndHit.size() - 1; thesize++){ cout << vectorOfpartitionsAndHit.at(thesize) << " " ; } cout << "channel " << vectorOfpartitionsAndHit.at(vectorOfpartitionsAndHit.size()-1) << endl; */ mapOfHits[currentChNumber+1] = vectorOfpartitionsAndHit; } // ---------- scintilators coordinates estimate for (int scintNum = 0 ; scintNum < 31 ; scintNum++){ if(this->getTriggerObjectNumber(1)->getChannel(scintNum+1)->hasHit() && vectorOfClusterNumberCombinations.size() == 1 ) { if (scintNum < 10) { scintilatorsCoordinates[scintNum+1] = graphXZ->Eval(0); topScintToString = boost::lexical_cast<string>(scintNum+1); } else { scintilatorsCoordinates[scintNum+1] = graphXZ->Eval(lastFitPoint+1); botScintToString = boost::lexical_cast<string>(scintNum+1); } } } } // get only vertical tracks from the A partition if there are only two scint hits if (keepRecoTrack && isVerticalTrack && !mapOfHits.empty() && scintilatorsCoordinates.size() == 2){ graphXZ->SetName(boost::lexical_cast<string>(eventNum).c_str()); string partition; if (mapOfHits.find(vectorOfReferenceChambers.at(0))->second.at(0) == 1) partition = "A"; else if (mapOfHits.find(vectorOfReferenceChambers.at(0))->second.at(0) == 2) partition = "B"; else partition = "C"; graphXZ->SetTitle(("Correlation factor is "+boost::lexical_cast<string>(graphXZ->GetCorrelationFactor()) + " trigger channels top: " + topScintToString + " bottom: " + botScintToString ).c_str()); if(abs(graphXZ->GetCorrelationFactor()) >= correlationFactor) { string scintCombination="_"+topScintToString+"_"+botScintToString+"_"+partition; TDirectory * dir = fileForRecoTracks->GetDirectory(scintCombination.c_str(),true); if(!dir) { //fileForRecoTracks->ls(); fileForRecoTracks->mkdir(scintCombination.c_str()) ; fileForRecoTracks->cd(""); } fileForRecoTracks->cd(scintCombination.c_str()); //cout << fileForRecoTracks->GetPath() << endl; } else{ fileForRecoTracks->cd("") ; fileForRecoTracks->cd("badTracks") ; } graphXZ->Write(graphXZ->GetName(),TObject::kOverwrite); fileForRecoTracks->cd(""); //fileForRecoTracks->Write(graphXZ->GetName(),TObject::kOverwrite); } fitfunc->Delete(); //histXZ->Delete(); graphXZ->Delete(); } return mapOfHits; }