Closed ladamczy closed 5 months ago
Skontaktowałem się z doktorem Rachwałem i sprawdził on u siebie działanie pliku treepart2.root (w nim są drzewa T, T1 i T2, gdzie pliki treepart1.root oraz treeparrent.root są puste), jednak coś z tym plikiem nie działa jak należy, mimo, że można czytać drzewa za pomocą TBrowser, to nawet szybki test poprzez interaktywną pracę z plikiem: root -l treepart2.root T->Draw("x") powoduje błędy w działaniu. Czy mogę prosić doktora o przygotowanie nowego pliku do testu kodu?
Jeśli kod działa to prosze przygotować jakiś sposób weryfikacji. że łączenie jest poprawne.
Jeden czek to sprawdzenie czy nie gubimy przypadków. Prosze przygotować liste numerów przypadków które się udało połączyć oraz listę których sie nie udalo połączyć (osobno dla jednego drzewa i osobno dla drugiego) i porównanie tego z lista którą otrzymamy analizując drzewa osobno.
Drugi to czek czy połaczone przypadki aby napewno sa połączone dobrze. Przygotuje nowe drzewo z kandydatami no K0 gdzie znajdzie sie jeszcze jedna zmienna (oprócz bumeru rau i eventu) która powinna mieć tą sama wrtość.
Narazie prosze skoncentrować sie zadaniu pierwszym.
Probowalem naprawic blad ktory wystepuje przy wykonaniu programu, ale okazuje sie ze nie wystepuje on przez zmiany zwiazane z czytaniem pliku z K0, tj. pozostaje on taki sam po zakomentowaniu moich zmian. Dla przypadku bez implementacji klasy jest identycznie.
(base) [krzemo@telesfor test2]$ ./build/MonteCarloEfficiency StUPC_dime_1_sim.root output.root st_dime_1.picoLambdaK0.root
Error in
Z tego co rozumiem powinienem zapisać do odpowiednich list dane których nie udało się poprawnie przypisać dla dwóch drzew, a następnie porównać te listy, czy przypadki tam na pewno nie występują, bo znaczyłoby to że przypadek sobie odpowiadał ale nie uległ połączeniu?
Czy np korzystając z tablicy przypadków zmatchowanych, porównać je z przypadkami z drugiego drzewa i te które nie występują w liście tych zmatchowanych poszukać w liście tych które z drugiego drzewa nie połączyły się poprawnie. Dostęp do możliwych K0 dla danego i-tego eventu powinien być z poziomu i-tej iteracji pętli?
Przez tydzień realizowałem zadania z numeryki oraz skonfigurowałem połączenie do konta na telesforze przy pomocy vscode.
W pliku przypadków zmatchowanych (*.txt) są 2624 przypadki odpowiadające K0, dokładnie tyle ile w pliku root. Czym różni się dostęp do przypadków dwoma sposobami: dla pętli: for (Long64_t i = 0; i < chain->GetEntries(); ++i) chain->GetEntry(i) | powoduje losowe rozmieszczenie przypadków po przechodzeniu po pętli po kolei upcEvt->getEventNumber() | powoduje zapis zgodny z przechodzoną pętlą czy to by znaczyło że przypadki w pierwszej z pętli nie są po kolei?
Aktuanie zajmuję się przepisywaniem tego na odpowiednią mapę (odpowiednie pliki klasy o tej samej nazwie z początkiem Map) tak by uniknąć przechodzenia w pętli po drugim pliku. Czy ta metoda będzie optymalna? w sensie stworzenia przez doktora nowego drzewa z nową zmienną wiązałoby się to wtedy z rozszerzeniem indeksowania takiej mapy, czy ta nowa wartość rozróżniałaby dany sposób przypadek?
Prubuję dokończyć implementację mapy, ale widzę że jeśli na 1 przypadek są możliwe co najmniej 2 K0 to konieczne byłoby umieszczenie wektora (danych przypadku) w wektorze (ilosci przypadków) co jak pamiętam doktor mówił jest już niepotrzebnie skomplikowane. Poza tym i tak w celu umieszczenia tych danych w mapie musze przejsc w petli po wszystkich wpisach wiecej jak raz. Czy teraz powinienem czekać na nowe drzewo, czy też jaki jest kolejny cel?
Z tego co rozumiem powinienem zapisać do odpowiednich list dane których nie udało się poprawnie przypisać dla dwóch drzew, a następnie porównać te listy, czy przypadki tam na pewno nie występują, bo znaczyłoby to że przypadek sobie odpowiadał ale nie uległ połączeniu?
generalnie tak. Ma Pan 3 drzewa, dwa wejściowe i jedno wynikowe. Trzeba zrobić liste przypadków z tych 3 drzew i sprawdzić czy wszystkie wspólne przypadki z drzew wejściowych znalazły sie w drzewie wyjściowym. Dodatkowo można sprawdzić zy krotność K0 w drzewie wejściowym i wyjściowym się zgadza.
Czy np korzystając z tablicy przypadków zmatchowanych, porównać je z przypadkami z drugiego drzewa i te które nie występują w liście tych zmatchowanych poszukać w liście tych które z drugiego drzewa nie połączyły się poprawnie.
troche zawile. Nie rozumiem.
Dostęp do możliwych K0 dla danego i-tego eventu powinien być z poziomu i-tej iteracji pętli?
tak
Przez tydzień realizowałem zadania z numeryki oraz skonfigurowałem połączenie do konta na telesforze przy pomocy vscode.
co Pan rozumie przez "zadania z numeryki" ? Prosze się podzielić konfiguracją połączenia przy pomocy vscode
W pliku przypadków zmatchowanych (*.txt) są 2624 przypadki odpowiadające K0, dokładnie tyle ile w pliku root.
Czym różni się dostęp do przypadków dwoma sposobami:
dla pętli: for (Long64_t i = 0; i < chain->GetEntries(); ++i) chain->GetEntry(i) | powoduje losowe rozmieszczenie przypadków po przechodzeniu po pętli po kolei
nie losowe, przypadki są czytane zgodnie z indeksem i (od 1 do 2624)
upcEvt->getEventNumber() | powoduje zapis zgodny z przechodzoną pętlą czy to by znaczyło że przypadki w pierwszej z pętli nie są po kolei?
nie rozumiem: upcEvt->getEventNumber() jest metoda która dla aktualnego przypadku zwraza numer zmiennej która jest która jest numerem przypadku (przypadku w ranie a nie w drzewie)
Aktuanie zajmuję się przepisywaniem tego na odpowiednią mapę (odpowiednie pliki klasy o tej samej nazwie z początkiem Map) tak by uniknąć przechodzenia w pętli po drugim pliku. Czy ta metoda będzie optymalna? w sensie stworzenia przez doktora nowego drzewa z nową zmienną wiązałoby się to wtedy z rozszerzeniem indeksowania takiej mapy, czy ta nowa wartość rozróżniałaby dany sposób przypadek?
musimy chyba porozmawiać ba ja nie rozumiem o czym Pan pisze
Prubuję dokończyć implementację mapy, ale widzę że jeśli na 1 przypadek są możliwe co najmniej 2 K0 to konieczne byłoby umieszczenie wektora (danych przypadku) w wektorze (ilosci przypadków) co jak pamiętam doktor mówił jest już niepotrzebnie skomplikowane. Poza tym i tak w celu umieszczenia tych danych w mapie musze przejsc w petli po wszystkich wpisach wiecej jak raz. Czy teraz powinienem czekać na nowe drzewo, czy też jaki jest kolejny cel?
Trudno jest mi napisac jaki jest kolejny cel bo nie wiem czy poprzedni cel został osiągnięty czy nie.
Czy jakieś postępy? Oczywiście w przypadku możemy mieć dowolna ilość kandydatów na K0, zatem musi to być wektor o dowolnej(zmiennej) długości. W obecnej implementacji (kiedy przypadki sa pokolei) nie musi Pan robić pętli po całych plikach. Wystrczy patrzeć na numery przypadków i czytać z tego pliku który ma aktualnie mniejsze numer . Podam przykład. Kolumna pierwsza przypadki na liście K0 kolumna 2 przypadki na w drzewie UPCDst
3 1 3 2 5 3 6 4 7 6 7 7 7 9 8 10
Pętla główna jest po drzewie UPCDst. pierwszy przypadek w drzewie UPCDst ma numer "1(UPC)" , czyta Pan pierwszy przypadek z drzewa K0 widzi Pan że ten przypadek ma numer "3(K0)" . Zatem wektor z K0 dla przypadku "1(UPC)" ma rozmiast 0. Czyta Pan kolejne przypadki z drzewa UPC tak długo aż znajdzie Pan przypadek >="3". Czyli przypadek "2(UPC) podobnie nie ma K0 czyli wektor z K0 ma rozmiar 0. Koleny przypadek w drzewie UPC ma numer "3(UPC)" czyli taki sam jak aktualny przypadek w drzewie K0. Teraz czytamy kolejne przypadki z drzewa K0 tak długo jak jak numer przypadku bedzie 3(K0). Czyli czytamy kolejno dwa przypadki. Jeden przypadek ma numer "3(K0)" a kolejny "5(K0). W drzewie UPC aktualnie jesteśmy przy przypadku "3(UPC)" dla tego przypadku tworzymy wektor K0 o długości 2 (dwa K0) i przechodzimy do kolejnych przypadków w drzewie UPC az dostaniemy numer (DST) >=5 . 5 to aktualny numer przypadku w drzewie K0. Kolejny przypadek w drzewie UPC ma numer 4(UPC) pzypisujemy mu wektor K0 o długości 0. Kolejny przypadek w drzewie UPC ma numer "6(UPC)", czyli jest wiekszy od aktualnego numeru przypadku w drzewie K0 (numer). Teraz czytamy z drzewa K0 tak długo jak dostaniemy numer przypadku K0 > od numeru przypadku UPC . Czyli czytamy kolejne dwa przypadku o numerze "6(K0)" i "7(K0) . Teraz dla aktualnego przypadku "6(UPC)" tworzymy wektor K0 o rozmiarze 1 i przechodzmy do kolejnego przypadku w drzewie UPC który ma numer "7(UPC) . Przechodzimy do drzewa K0 i czytamy kolejne przypadki az numer K0 będzie > 7 , czyli czytamy kolejne trzy przypadki "7(K0)", "7(K0)" i "8(K0)" . Teraz dla aktualnego przypadku "7(UPC)" tworzymy wektor K0 o długości 3 i czytamy kolejny przypadek z drzewa UPC. Jak Pan widzi nie robimy kilku pętli po drzewach. Kazdy przypadek w drzewach K0 i UPC czytamy raz i nie ma potrzeby tworzenia map.
W pliku znajduje się instrukcja umożliwiająca połączenie do zdalnego hosta poprzez innego zdalnego hosta w vs code. W konfiguracji poprowadził mnie Adam Wątroba, przepisałem jego instrukcje do pliku.
Na spotkaniu przedstawiłem poprawnie już działający kod. Czy doktor może zobaczyć czy tak to właśnie miało wyglądać? Co jest następne w kolejności do wykonania?
W pliku znajduje się instrukcja umożliwiająca połączenie do zdalnego hosta poprzez innego zdalnego hosta w vs code. W konfiguracji poprowadził mnie Adam Wątroba, przepisałem jego instrukcje do pliku.
ale daje tylko dostęp do taurusa. Aby mieć dostep np. do konta na telesforze które Panu utworzyłem ti chyba trzeba zkonfigurowac tunelowanie a nie proste ssh ?
Przepraszam, przeoczyłem te linijke w konfiguracji
ProxyJump NAZWA_HOSTA_1
Teraz działa
Wydaje sie że program działa poprawnie. Prosze go nie modyfikować (test2) Utworzyć nowy projekt (np. test3) i spróbować dodać wektory z drzewa K0 do drzewa upcDST. Widze to tak
Ponieważ będziemy procesować pojedyncze pliki prosze zrezygnować z tworzenia chain i działać bezpośrednio na TTree. Otwiera Pan drzewo upcDST z opcja do zapisu (update):
TFile f("argv[1]","update"); TTree UPCEvent = (TTree) f.Get("mUPCEvent"); static StUPCEvent *upcEvt = 0x0; UPCEvent->SetBranchAddress("mUPCEvent", &upcEvt);
std::vector
for (Long64_t i = 0; i < UPCEvent->GetEntries(); ++i) Read_K0.ProcessData(i, upcEvt, UPCEvent, chain2); eventIdVectors = Read_K0.eventIdVectors; beventIdVectors->Fill(); ...... pozostałe wektory z dzrewa K0 ...... }
UPCEvent->Write(); f.Close();
Niech Pan usunie pozostałe częsci kodu MCEfficiency i może Pan zmenić nazwę programu na np. MergeK0withUPCDst
Przepraszam, straciłem możliwość łączenia się do konta na telesforze, zarówno w sesji zdalnej jak i przy łączeniu z terminala
Tak, nie ma dostępu zdalnego do telesfora. Postaram sie to jutro naprawić.
Jest juz dostep zfalny do telesfora.
Analizowałem ten wyciek pamięci i program gdb wskazał mi, że dzieje się to od razu po rozpoczęciu funkcji main, gdzie jeszcze nic nie jest alokowane. Wygląda jakby był to problem na etapie dołączanych bibliotek, ponowne wykonanie skryptu z katalogu star-upc nie pomogło.
Nie mam pomysłu co może powodować wyżej wspomniany wyciek. Udostępniłem doktorowi dostęp do projektu w overleafie, jeśli doktor ma jakieś materiały, które mógbym przerobić w celu zapisania wstępu dla pracy, to mógłbym się nim równolegle zająć.
nie wiem o jakim wycieku Pan pisze.
Po pierwsze
tutaj
UPCTree->SetBranchAddress("mUPCTree", &upcEvt);
mamy nazwe brancha a nie tree. Zatem zamiast mUPCTree powinno być mUPCEvent. O tym już mówiliśmy tydzień temu na zebraniu.
Po drugie
przed zapisem
UPCTree->Write();
powinnien Pan przejść do odpowiedniej kartoteki np.
file1.cd();
Po trzecie
w obecnej konfiguracji bede dwie wersje drzewa UPCTree (stara i nowa) . Jesli chcemy mieć tylko nową to zapis powinien być taki
UPCTree->Write("", TObject::kOverwrite);
Po spotkaniu wysłałem zaległy kod łączący, jakie jest następne zadanie jakim teraz powinienem się zająć?
Zamykam to issue. Ostatecznie kod nie będzie uzywany w STAR. Tak bywa.
W kartotece share dodałem trzy pliki z drzewami. W treepart1 są trzy zmienne: Run, Event, x . W treepart2 są też trzy zmienne: Run, Event, y .
Chodzi o to aby napisać program który czyta równocześnie treepart1 i treepart2 i tworzy nowy plik (z nowym drzewem) zawierającym cztery zmienne: Run, Event, x, y.
Każdy przypadek ma unikalny zestaw pary: Run, Event . Obecny przykład jest bardzo prosty: kolejne przypadki w obu drzewach mają ten sam zestaw: Run, Event więc nie ma potrzeby wyszukiwania w jednym drzewie pasującej pary Run, Event w drugim drzewie.
Definicja struktury drzew jest taka:
TFile f1 = new TFile("treepart1.root","recreate"); TTree T1 = new TTree("T1","");
T1->Branch("Run",&Run,"Run/I"); T1->Branch("Event",&Event,"Event/I"); T1->Branch("x",&x,"x/F");
TFile f2 = new TFile("treepart2.root","recreate"); TTree T2 = new TTree("T2","");
T2->Branch("Run",&Run,"Run/I"); T2->Branch("Event",&Event,"Event/I"); T2->Branch("y",&x,"y/F");
Przykład jak tworzyć/czytać drzewa jest tutaj:
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwju_JqF78f-AhUSl4sKHR3rByIQFnoECC4QAQ&url=https%3A%2F%2Froot.cern%2Fdoc%2Fmaster%2Ftree1_8C_source.html&usg=AOvVaw0RVax1Bny5RA5EKOKNFTl1
Chodzi o to aby przerobić funkcje tree1r aby zamiast tworzyć histogramy tworzył nowe drzewo (podobnie jak tree1w)
Jak Pan to zrobi to skomplikujemy troche zadanie.
Wynikiem działania programu ma być plik treeparent.root (też w kartotece share)